Merge "App Crashes: Clarify mute option" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index ae343cd..5d28d2c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -104,6 +104,7 @@
     field public static final java.lang.String READ_WRITE_CONTACT_METADATA = "android.permission.READ_WRITE_CONTACT_METADATA";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
+    field public static final java.lang.String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST";
     field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
     field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
     field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
@@ -197,7 +198,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int abiOverride = 16844054; // 0x1010516
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -1364,6 +1364,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
+    field public static final int use32bitAbi = 16844054; // 0x1010516
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1375,6 +1376,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
+    field public static final int version = 16844058; // 0x101051a
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -4273,6 +4275,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -5224,6 +5227,7 @@
 
   public class NotificationManager {
     method public android.app.AutomaticZenRule addAutomaticZenRule(android.app.AutomaticZenRule);
+    method public boolean areNotificationsEnabled();
     method public void cancel(int);
     method public void cancel(java.lang.String, int);
     method public void cancelAll();
@@ -5231,6 +5235,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
+    method public int getImportance(java.lang.String);
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -5925,7 +5930,7 @@
     method public void setMaximumTimeToLock(android.content.ComponentName, long);
     method public void setOrganizationColor(android.content.ComponentName, int);
     method public void setOrganizationName(android.content.ComponentName, java.lang.String);
-    method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
+    method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
     method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
     method public void setPasswordHistoryLength(android.content.ComponentName, int);
     method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -8509,6 +8514,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
     field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
@@ -8528,7 +8534,6 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
-    field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
     field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
     field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -9396,6 +9401,7 @@
     field public int flags;
     field public java.lang.String name;
     field public int reqGlEsVersion;
+    field public int version;
   }
 
   public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -9674,6 +9680,7 @@
     method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -19218,7 +19225,6 @@
     method public double getElevationUncertaintyInDeg();
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
-    method public byte getPrn();
     method public double getPseudorangeInMeters();
     method public double getPseudorangeRateCarrierInMetersPerSec();
     method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
@@ -19229,6 +19235,7 @@
     method public long getReceivedGpsTowUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
+    method public short getSvid();
     method public short getTimeFromLastBitInMs();
     method public double getTimeOffsetInNs();
     method public boolean hasAzimuthInDeg();
@@ -19288,7 +19295,6 @@
     method public void setElevationUncertaintyInDeg(double);
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
-    method public void setPrn(byte);
     method public void setPseudorangeInMeters(double);
     method public void setPseudorangeRateCarrierInMetersPerSec(double);
     method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
@@ -19299,6 +19305,7 @@
     method public void setReceivedGpsTowUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
+    method public void setSvid(short);
     method public void setTimeFromLastBitInMs(short);
     method public void setTimeOffsetInNs(double);
     method public void setUsedInFix(boolean);
@@ -19353,17 +19360,17 @@
     method public int describeContents();
     method public byte[] getData();
     method public short getMessageId();
-    method public byte getPrn();
     method public short getStatus();
     method public short getSubmessageId();
+    method public short getSvid();
     method public byte getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
     method public void setMessageId(short);
-    method public void setPrn(byte);
     method public void setStatus(short);
     method public void setSubmessageId(short);
+    method public void setSvid(short);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
@@ -19409,8 +19416,8 @@
     method public int getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
-    method public int getPrn(int);
     method public float getSnr(int);
+    method public int getSvid(int);
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
@@ -22871,6 +22878,7 @@
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -22906,7 +22914,9 @@
     method public android.content.pm.ServiceInfo getServiceInfo();
     method public int getTunerCount();
     method public int getType();
+    method public boolean isHidden(android.content.Context);
     method public boolean isPassthroughInput();
+    method public java.lang.CharSequence loadCustomLabel(android.content.Context);
     method public android.graphics.drawable.Drawable loadIcon(android.content.Context);
     method public java.lang.CharSequence loadLabel(android.content.Context);
     method public void writeToParcel(android.os.Parcel, int);
@@ -22946,9 +22956,8 @@
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
     field public static final java.lang.String META_DATA_CONTENT_RATING_SYSTEMS = "android.media.tv.metadata.CONTENT_RATING_SYSTEMS";
-    field public static final int RECORDING_ERROR_CONNECTION_FAILED = 1; // 0x1
-    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 2; // 0x2
-    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 3; // 0x3
+    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1; // 0x1
+    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 2; // 0x2
     field public static final int RECORDING_ERROR_UNKNOWN = 0; // 0x0
     field public static final long TIME_SHIFT_INVALID_TIME = -9223372036854775808L; // 0x8000000000000000L
     field public static final int TIME_SHIFT_STATUS_AVAILABLE = 3; // 0x3
@@ -22968,7 +22977,7 @@
     method public void onInputRemoved(java.lang.String);
     method public void onInputStateChanged(java.lang.String, int);
     method public void onInputUpdated(java.lang.String);
-    method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
+    method public void onTvInputInfoUpdated(android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
@@ -22976,7 +22985,7 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
     method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
-    method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
+    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -22991,14 +23000,13 @@
 
   public static abstract class TvInputService.RecordingSession {
     ctor public TvInputService.RecordingSession(android.content.Context);
-    method public void notifyConnected();
     method public void notifyError(int);
-    method public void notifyRecordingStarted();
     method public void notifyRecordingStopped(android.net.Uri);
-    method public abstract void onConnect(android.net.Uri);
-    method public abstract void onDisconnect();
-    method public abstract void onStartRecording();
+    method public void notifyTuned();
+    method public abstract void onRelease();
+    method public abstract void onStartRecording(android.net.Uri);
     method public abstract void onStopRecording();
+    method public abstract void onTune(android.net.Uri);
   }
 
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
@@ -23041,19 +23049,19 @@
 
   public class TvRecordingClient {
     ctor public TvRecordingClient(android.content.Context, java.lang.String, android.media.tv.TvRecordingClient.RecordingCallback, android.os.Handler);
-    method public void connect(java.lang.String, android.net.Uri);
-    method public void disconnect();
-    method public void startRecording();
+    method public void release();
+    method public void startRecording(android.net.Uri);
     method public void stopRecording();
+    method public void tune(java.lang.String, android.net.Uri);
   }
 
   public static abstract class TvRecordingClient.RecordingCallback {
     ctor public TvRecordingClient.RecordingCallback();
-    method public void onConnected();
-    method public void onDisconnected();
+    method public void onConnectionFailed(java.lang.String);
+    method public void onDisconnected(java.lang.String);
     method public void onError(int);
-    method public void onRecordingStarted();
     method public void onRecordingStopped(android.net.Uri);
+    method public void onTuned();
   }
 
   public final class TvTrackInfo implements android.os.Parcelable {
@@ -23065,6 +23073,7 @@
     method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
     method public final int getType();
+    method public final byte getVideoActiveFormatDescription();
     method public final float getVideoFrameRate();
     method public final int getVideoHeight();
     method public final float getVideoPixelAspectRatio();
@@ -23084,6 +23093,7 @@
     method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.CharSequence);
     method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
     method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoActiveFormatDescription(byte);
     method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
     method public final android.media.tv.TvTrackInfo.Builder setVideoHeight(int);
     method public final android.media.tv.TvTrackInfo.Builder setVideoPixelAspectRatio(float);
@@ -28564,7 +28574,6 @@
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
-    field public static java.lang.String DIRECTORY_HOME;
     field public static java.lang.String DIRECTORY_MOVIES;
     field public static java.lang.String DIRECTORY_MUSIC;
     field public static java.lang.String DIRECTORY_NOTIFICATIONS;
@@ -29060,6 +29069,7 @@
     method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
     method public static final int getUidForName(java.lang.String);
     method public static final boolean is64Bit();
+    method public static boolean isApplicationUid(int);
     method public static final void killProcess(int);
     method public static final int myPid();
     method public static final int myTid();
@@ -29240,6 +29250,7 @@
   public final class UserHandle implements android.os.Parcelable {
     ctor public UserHandle(android.os.Parcel);
     method public int describeContents();
+    method public static android.os.UserHandle getUserHandleForUid(int);
     method public static android.os.UserHandle readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     method public static void writeToParcel(android.os.UserHandle, android.os.Parcel);
@@ -29353,11 +29364,27 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
   }
 
+  public class StorageVolume implements android.os.Parcelable {
+    method public android.content.Intent createAccessIntent(java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getDescription(android.content.Context);
+    method public java.lang.String getState();
+    method public java.lang.String getUuid();
+    method public boolean isEmulated();
+    method public boolean isPrimary();
+    method public boolean isRemovable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.storage.StorageVolume> CREATOR;
+    field public static final java.lang.String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME";
+  }
+
 }
 
 package android.preference {
@@ -31457,6 +31484,8 @@
   }
 
   protected static abstract interface ContactsContract.PhoneLookupColumns {
+    field public static final java.lang.String CONTACT_ID = "contact_id";
+    field public static final java.lang.String DATA_ID = "data_id";
     field public static final java.lang.String LABEL = "label";
     field public static final java.lang.String NORMALIZED_NUMBER = "normalized_number";
     field public static final java.lang.String NUMBER = "number";
@@ -31720,6 +31749,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
@@ -31740,7 +31770,7 @@
     method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
     method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
-    method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public void removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final void revokeDocumentPermission(java.lang.String);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
@@ -32140,6 +32170,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_SCREEN_READER_TUTORIAL = "android.settings.SCREEN_READER_TUTORIAL";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -34044,6 +34075,7 @@
 
   public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+    method public byte[] getAttestationChallenge();
     method public java.lang.String[] getBlockModes();
     method public java.util.Date getCertificateNotAfter();
     method public java.util.Date getCertificateNotBefore();
@@ -34068,6 +34100,7 @@
     ctor public KeyGenParameterSpec.Builder(java.lang.String, int);
     method public android.security.keystore.KeyGenParameterSpec build();
     method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+    method public android.security.keystore.KeyGenParameterSpec.Builder setAttestationChallenge(byte[]);
     method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date);
@@ -37780,6 +37813,7 @@
     method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -40660,6 +40694,21 @@
     method public static android.view.FocusFinder getInstance();
   }
 
+  public final class FrameMetrics {
+    ctor public FrameMetrics(android.view.FrameMetrics);
+    method public long getMetric(int);
+    field public static final int ANIMATION_DURATION = 2; // 0x2
+    field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6
+    field public static final int DRAW_DURATION = 4; // 0x4
+    field public static final int FIRST_DRAW_FRAME = 9; // 0x9
+    field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
+    field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
+    field public static final int SYNC_DURATION = 5; // 0x5
+    field public static final int TOTAL_DURATION = 8; // 0x8
+    field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+  }
+
   public abstract class FrameStats {
     ctor public FrameStats();
     method public final long getEndTimeNano();
@@ -43163,6 +43212,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
+    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -43214,6 +43264,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
+    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -43339,6 +43390,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.FrameMetricsListener {
+    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  }
+
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
     method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
   }
@@ -51449,7 +51504,6 @@
     method public static int getLength(java.lang.Object);
     method public static long getLong(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
     method public static short getShort(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static java.lang.Object newArray(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int...) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException;
     method public static void set(java.lang.Object, int, java.lang.Object) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
@@ -52125,7 +52179,6 @@
 
   public class InetAddress implements java.io.Serializable {
     method public byte[] getAddress();
-    method public byte[] getAddressInternal();
     method public static java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(java.lang.String, byte[]) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(byte[]) throws java.net.UnknownHostException;
@@ -52399,7 +52452,7 @@
     method protected abstract void connect(java.net.InetAddress, int) throws java.io.IOException;
     method protected abstract void connect(java.net.SocketAddress, int) throws java.io.IOException;
     method protected abstract void create(boolean) throws java.io.IOException;
-    method public java.io.FileDescriptor getFileDescriptor();
+    method protected java.io.FileDescriptor getFileDescriptor();
     method protected java.net.InetAddress getInetAddress();
     method protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
     method protected int getLocalPort();
@@ -52941,10 +52994,6 @@
 
 package java.nio.channels {
 
-  public class AcceptPendingException extends java.lang.IllegalStateException {
-    ctor public AcceptPendingException();
-  }
-
   public class AlreadyBoundException extends java.lang.IllegalStateException {
     ctor public AlreadyBoundException();
   }
@@ -52953,68 +53002,10 @@
     ctor public AlreadyConnectedException();
   }
 
-  public abstract interface AsynchronousByteChannel implements java.nio.channels.AsynchronousChannel {
-    method public abstract void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-  }
-
-  public abstract interface AsynchronousChannel implements java.nio.channels.Channel {
-    method public abstract void close() throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousChannelGroup {
-    ctor protected AsynchronousChannelGroup(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract boolean isShutdown();
-    method public abstract boolean isTerminated();
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void shutdown();
-    method public abstract void shutdownNow() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withCachedThreadPool(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withFixedThreadPool(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withThreadPool(java.util.concurrent.ExecutorService) throws java.io.IOException;
-  }
-
   public class AsynchronousCloseException extends java.nio.channels.ClosedChannelException {
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousServerSocketChannel implements java.nio.channels.AsynchronousChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousServerSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract void accept(A, java.nio.channels.CompletionHandler<java.nio.channels.AsynchronousSocketChannel, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.AsynchronousSocketChannel> accept();
-    method public final java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousSocketChannel implements java.nio.channels.AsynchronousByteChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract java.nio.channels.AsynchronousSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract void connect(java.net.SocketAddress, A, java.nio.channels.CompletionHandler<java.lang.Void, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Void> connect(java.net.SocketAddress);
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void read(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void read(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-    method public abstract java.nio.channels.AsynchronousSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownInput() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownOutput() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-  }
-
   public abstract interface ByteChannel implements java.nio.channels.ReadableByteChannel java.nio.channels.WritableByteChannel {
   }
 
@@ -53031,9 +53022,7 @@
     method public static java.nio.channels.ReadableByteChannel newChannel(java.io.InputStream);
     method public static java.nio.channels.WritableByteChannel newChannel(java.io.OutputStream);
     method public static java.io.InputStream newInputStream(java.nio.channels.ReadableByteChannel);
-    method public static java.io.InputStream newInputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.OutputStream newOutputStream(java.nio.channels.WritableByteChannel);
-    method public static java.io.OutputStream newOutputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.lang.String);
     method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int);
@@ -53052,16 +53041,11 @@
     ctor public ClosedSelectorException();
   }
 
-  public abstract interface CompletionHandler {
-    method public abstract void completed(V, A);
-    method public abstract void failed(java.lang.Throwable, A);
-  }
-
   public class ConnectionPendingException extends java.lang.IllegalStateException {
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
@@ -53140,40 +53124,14 @@
     ctor public IllegalBlockingModeException();
   }
 
-  public class IllegalChannelGroupException extends java.lang.IllegalArgumentException {
-    ctor public IllegalChannelGroupException();
-  }
-
   public class IllegalSelectorException extends java.lang.IllegalArgumentException {
     ctor public IllegalSelectorException();
   }
 
-  public class InterruptedByTimeoutException extends java.io.IOException {
-    ctor public InterruptedByTimeoutException();
-  }
-
   public abstract interface InterruptibleChannel implements java.nio.channels.Channel {
     method public abstract void close() throws java.io.IOException;
   }
 
-  public abstract class MembershipKey {
-    ctor protected MembershipKey();
-    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.MulticastChannel channel();
-    method public abstract void drop();
-    method public abstract java.net.InetAddress group();
-    method public abstract boolean isValid();
-    method public abstract java.net.NetworkInterface networkInterface();
-    method public abstract java.net.InetAddress sourceAddress();
-    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
-  }
-
-  public abstract interface MulticastChannel implements java.nio.channels.NetworkChannel {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
-  }
-
   public abstract interface NetworkChannel implements java.nio.channels.Channel {
     method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
@@ -53223,10 +53181,6 @@
     method public final int validOps();
   }
 
-  public class ReadPendingException extends java.lang.IllegalStateException {
-    ctor public ReadPendingException();
-  }
-
   public abstract interface ReadableByteChannel implements java.nio.channels.Channel {
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
   }
@@ -53304,10 +53258,6 @@
     method public final int validOps();
   }
 
-  public class ShutdownChannelGroupException extends java.lang.IllegalStateException {
-    ctor public ShutdownChannelGroupException();
-  }
-
   public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
@@ -53343,10 +53293,6 @@
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
   }
 
-  public class WritePendingException extends java.lang.IllegalStateException {
-    ctor public WritePendingException();
-  }
-
 }
 
 package java.nio.channels.spi {
@@ -53393,15 +53339,6 @@
     method protected abstract java.nio.channels.SelectionKey register(java.nio.channels.spi.AbstractSelectableChannel, int, java.lang.Object);
   }
 
-  public abstract class AsynchronousChannelProvider {
-    ctor protected AsynchronousChannelProvider();
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel openAsynchronousSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.spi.AsynchronousChannelProvider provider();
-  }
-
   public abstract class SelectorProvider {
     ctor protected SelectorProvider();
     method public java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
@@ -54216,7 +54153,6 @@
   public abstract class Signature extends java.security.SignatureSpi {
     ctor protected Signature(java.lang.String);
     method public final java.lang.String getAlgorithm();
-    method public java.security.SignatureSpi getCurrentSpi();
     method public static java.security.Signature getInstance(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public static java.security.Signature getInstance(java.lang.String, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
     method public static java.security.Signature getInstance(java.lang.String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
@@ -56756,13 +56692,11 @@
     method public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale);
     method public java.lang.String getInternationalCurrencySymbol();
     method public char getMinusSign();
-    method public java.lang.String getMinusSignString();
     method public char getMonetaryDecimalSeparator();
     method public java.lang.String getNaN();
     method public char getPatternSeparator();
     method public char getPerMill();
     method public char getPercent();
-    method public java.lang.String getPercentString();
     method public char getZeroDigit();
     method public void setCurrency(java.util.Currency);
     method public void setCurrencySymbol(java.lang.String);
@@ -58015,8 +57949,11 @@
     method public static boolean equals(java.lang.Object, java.lang.Object);
     method public static int hash(java.lang.Object...);
     method public static int hashCode(java.lang.Object);
+    method public static boolean isNull(java.lang.Object);
+    method public static boolean nonNull(java.lang.Object);
     method public static T requireNonNull(T);
     method public static T requireNonNull(T, java.lang.String);
+    method public static T requireNonNull(T, java.util.function.Supplier<java.lang.String>);
     method public static java.lang.String toString(java.lang.Object);
     method public static java.lang.String toString(java.lang.Object, java.lang.String);
   }
@@ -59721,6 +59658,217 @@
 
 }
 
+package java.util.function {
+
+  public abstract interface BiConsumer {
+    method public abstract void accept(T, U);
+    method public default java.util.function.BiConsumer<T, U> andThen(java.util.function.BiConsumer<? super T, ? super U>);
+  }
+
+  public abstract interface BiFunction {
+    method public default java.util.function.BiFunction<T, U, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T, U);
+  }
+
+  public abstract interface BiPredicate {
+    method public default java.util.function.BiPredicate<T, U> and(java.util.function.BiPredicate<? super T, ? super U>);
+    method public default java.util.function.BiPredicate<T, U> negate();
+    method public default java.util.function.BiPredicate<T, U> or(java.util.function.BiPredicate<? super T, ? super U>);
+    method public abstract boolean test(T, U);
+  }
+
+  public abstract interface BinaryOperator implements java.util.function.BiFunction {
+    method public static java.util.function.BinaryOperator<T> maxBy(java.util.Comparator<? super T>);
+    method public static java.util.function.BinaryOperator<T> minBy(java.util.Comparator<? super T>);
+  }
+
+  public abstract interface BooleanSupplier {
+    method public abstract boolean getAsBoolean();
+  }
+
+  public abstract interface Consumer {
+    method public abstract void accept(T);
+    method public default java.util.function.Consumer<T> andThen(java.util.function.Consumer<? super T>);
+  }
+
+  public abstract interface DoubleBinaryOperator {
+    method public abstract double applyAsDouble(double, double);
+  }
+
+  public abstract interface DoubleConsumer {
+    method public abstract void accept(double);
+    method public default java.util.function.DoubleConsumer andThen(java.util.function.DoubleConsumer);
+  }
+
+  public abstract interface DoubleFunction {
+    method public abstract R apply(double);
+  }
+
+  public abstract interface DoublePredicate {
+    method public default java.util.function.DoublePredicate and(java.util.function.DoublePredicate);
+    method public default java.util.function.DoublePredicate negate();
+    method public default java.util.function.DoublePredicate or(java.util.function.DoublePredicate);
+    method public abstract boolean test(double);
+  }
+
+  public abstract interface DoubleSupplier {
+    method public abstract double getAsDouble();
+  }
+
+  public abstract interface DoubleToIntFunction {
+    method public abstract int applyAsInt(double);
+  }
+
+  public abstract interface DoubleToLongFunction {
+    method public abstract long applyAsLong(double);
+  }
+
+  public abstract interface DoubleUnaryOperator {
+    method public default java.util.function.DoubleUnaryOperator andThen(java.util.function.DoubleUnaryOperator);
+    method public abstract double applyAsDouble(double);
+    method public default java.util.function.DoubleUnaryOperator compose(java.util.function.DoubleUnaryOperator);
+    method public static java.util.function.DoubleUnaryOperator identity();
+  }
+
+  public abstract interface Function {
+    method public default java.util.function.Function<T, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T);
+    method public default java.util.function.Function<V, R> compose(java.util.function.Function<? super V, ? extends T>);
+    method public static java.util.function.Function<T, T> identity();
+  }
+
+  public abstract interface IntBinaryOperator {
+    method public abstract int applyAsInt(int, int);
+  }
+
+  public abstract interface IntConsumer {
+    method public abstract void accept(int);
+    method public default java.util.function.IntConsumer andThen(java.util.function.IntConsumer);
+  }
+
+  public abstract interface IntFunction {
+    method public abstract R apply(int);
+  }
+
+  public abstract interface IntPredicate {
+    method public default java.util.function.IntPredicate and(java.util.function.IntPredicate);
+    method public default java.util.function.IntPredicate negate();
+    method public default java.util.function.IntPredicate or(java.util.function.IntPredicate);
+    method public abstract boolean test(int);
+  }
+
+  public abstract interface IntSupplier {
+    method public abstract int getAsInt();
+  }
+
+  public abstract interface IntToDoubleFunction {
+    method public abstract double applyAsDouble(int);
+  }
+
+  public abstract interface IntToLongFunction {
+    method public abstract long applyAsLong(int);
+  }
+
+  public abstract interface IntUnaryOperator {
+    method public default java.util.function.IntUnaryOperator andThen(java.util.function.IntUnaryOperator);
+    method public abstract int applyAsInt(int);
+    method public default java.util.function.IntUnaryOperator compose(java.util.function.IntUnaryOperator);
+    method public static java.util.function.IntUnaryOperator identity();
+  }
+
+  public abstract interface LongBinaryOperator {
+    method public abstract long applyAsLong(long, long);
+  }
+
+  public abstract interface LongConsumer {
+    method public abstract void accept(long);
+    method public default java.util.function.LongConsumer andThen(java.util.function.LongConsumer);
+  }
+
+  public abstract interface LongFunction {
+    method public abstract R apply(long);
+  }
+
+  public abstract interface LongPredicate {
+    method public default java.util.function.LongPredicate and(java.util.function.LongPredicate);
+    method public default java.util.function.LongPredicate negate();
+    method public default java.util.function.LongPredicate or(java.util.function.LongPredicate);
+    method public abstract boolean test(long);
+  }
+
+  public abstract interface LongSupplier {
+    method public abstract long getAsLong();
+  }
+
+  public abstract interface LongToDoubleFunction {
+    method public abstract double applyAsDouble(long);
+  }
+
+  public abstract interface LongToIntFunction {
+    method public abstract int applyAsInt(long);
+  }
+
+  public abstract interface LongUnaryOperator {
+    method public default java.util.function.LongUnaryOperator andThen(java.util.function.LongUnaryOperator);
+    method public abstract long applyAsLong(long);
+    method public default java.util.function.LongUnaryOperator compose(java.util.function.LongUnaryOperator);
+    method public static java.util.function.LongUnaryOperator identity();
+  }
+
+  public abstract interface ObjDoubleConsumer {
+    method public abstract void accept(T, double);
+  }
+
+  public abstract interface ObjIntConsumer {
+    method public abstract void accept(T, int);
+  }
+
+  public abstract interface ObjLongConsumer {
+    method public abstract void accept(T, long);
+  }
+
+  public abstract interface Predicate {
+    method public default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T>);
+    method public static java.util.function.Predicate<T> isEqual(java.lang.Object);
+    method public default java.util.function.Predicate<T> negate();
+    method public default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T>);
+    method public abstract boolean test(T);
+  }
+
+  public abstract interface Supplier {
+    method public abstract T get();
+  }
+
+  public abstract interface ToDoubleBiFunction {
+    method public abstract double applyAsDouble(T, U);
+  }
+
+  public abstract interface ToDoubleFunction {
+    method public abstract double applyAsDouble(T);
+  }
+
+  public abstract interface ToIntBiFunction {
+    method public abstract int applyAsInt(T, U);
+  }
+
+  public abstract interface ToIntFunction {
+    method public abstract int applyAsInt(T);
+  }
+
+  public abstract interface ToLongBiFunction {
+    method public abstract long applyAsLong(T, U);
+  }
+
+  public abstract interface ToLongFunction {
+    method public abstract long applyAsLong(T);
+  }
+
+  public abstract interface UnaryOperator implements java.util.function.Function {
+    method public static java.util.function.UnaryOperator<T> identity();
+  }
+
+}
+
 package java.util.jar {
 
   public class Attributes implements java.lang.Cloneable java.util.Map {
@@ -62455,14 +62603,6 @@
     method public abstract boolean isDestroyed();
   }
 
-  public abstract deprecated class Policy {
-    ctor protected Policy();
-    method public abstract java.security.PermissionCollection getPermissions(javax.security.auth.Subject, java.security.CodeSource);
-    method public static javax.security.auth.Policy getPolicy();
-    method public abstract void refresh();
-    method public static void setPolicy(javax.security.auth.Policy);
-  }
-
   public final class PrivateCredentialPermission extends java.security.Permission {
     ctor public PrivateCredentialPermission(java.lang.String, java.lang.String);
     method public boolean equals(java.lang.Object);
@@ -62527,43 +62667,6 @@
 
 package javax.security.auth.login {
 
-  public class AppConfigurationEntry {
-    ctor public AppConfigurationEntry(java.lang.String, javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag, java.util.Map<java.lang.String, ?>);
-    method public javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag getControlFlag();
-    method public java.lang.String getLoginModuleName();
-    method public java.util.Map<java.lang.String, ?> getOptions();
-  }
-
-  public static class AppConfigurationEntry.LoginModuleControlFlag {
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag OPTIONAL;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUIRED;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUISITE;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag SUFFICIENT;
-  }
-
-  public abstract class Configuration {
-    ctor protected Configuration();
-    method public abstract javax.security.auth.login.AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String);
-    method public static javax.security.auth.login.Configuration getConfiguration();
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters) throws java.security.NoSuchAlgorithmException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public javax.security.auth.login.Configuration.Parameters getParameters();
-    method public java.security.Provider getProvider();
-    method public java.lang.String getType();
-    method public void refresh();
-    method public static void setConfiguration(javax.security.auth.login.Configuration);
-  }
-
-  public static abstract interface Configuration.Parameters {
-  }
-
-  public abstract class ConfigurationSpi {
-    ctor public ConfigurationSpi();
-    method protected abstract javax.security.auth.login.AppConfigurationEntry[] engineGetAppConfigurationEntry(java.lang.String);
-    method protected void engineRefresh();
-  }
-
   public class LoginException extends java.security.GeneralSecurityException {
     ctor public LoginException();
     ctor public LoginException(java.lang.String);
diff --git a/api/system-current.txt b/api/system-current.txt
index bcd39fe..a2943ff 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -293,7 +293,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int abiOverride = 16844054; // 0x1010516
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -1464,6 +1463,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
+    field public static final int use32bitAbi = 16844054; // 0x1010516
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1475,6 +1475,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
+    field public static final int version = 16844058; // 0x101051a
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -4406,6 +4407,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -5357,6 +5359,7 @@
 
   public class NotificationManager {
     method public android.app.AutomaticZenRule addAutomaticZenRule(android.app.AutomaticZenRule);
+    method public boolean areNotificationsEnabled();
     method public void cancel(int);
     method public void cancel(java.lang.String, int);
     method public void cancelAll();
@@ -5364,6 +5367,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
+    method public int getImportance(java.lang.String);
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -6072,7 +6076,7 @@
     method public void setMaximumTimeToLock(android.content.ComponentName, long);
     method public void setOrganizationColor(android.content.ComponentName, int);
     method public void setOrganizationName(android.content.ComponentName, java.lang.String);
-    method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
+    method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
     method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
     method public void setPasswordHistoryLength(android.content.ComponentName, int);
     method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -8816,6 +8820,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
     field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
@@ -8835,7 +8840,6 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
-    field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
     field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
     field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -9742,6 +9746,7 @@
     field public int flags;
     field public java.lang.String name;
     field public int reqGlEsVersion;
+    field public int version;
   }
 
   public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -10024,6 +10029,7 @@
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -20399,7 +20405,6 @@
     method public double getElevationUncertaintyInDeg();
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
-    method public byte getPrn();
     method public double getPseudorangeInMeters();
     method public double getPseudorangeRateCarrierInMetersPerSec();
     method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
@@ -20410,6 +20415,7 @@
     method public long getReceivedGpsTowUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
+    method public short getSvid();
     method public short getTimeFromLastBitInMs();
     method public double getTimeOffsetInNs();
     method public boolean hasAzimuthInDeg();
@@ -20469,7 +20475,6 @@
     method public void setElevationUncertaintyInDeg(double);
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
-    method public void setPrn(byte);
     method public void setPseudorangeInMeters(double);
     method public void setPseudorangeRateCarrierInMetersPerSec(double);
     method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
@@ -20480,6 +20485,7 @@
     method public void setReceivedGpsTowUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
+    method public void setSvid(short);
     method public void setTimeFromLastBitInMs(short);
     method public void setTimeOffsetInNs(double);
     method public void setUsedInFix(boolean);
@@ -20534,17 +20540,17 @@
     method public int describeContents();
     method public byte[] getData();
     method public short getMessageId();
-    method public byte getPrn();
     method public short getStatus();
     method public short getSubmessageId();
+    method public short getSvid();
     method public byte getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
     method public void setMessageId(short);
-    method public void setPrn(byte);
     method public void setStatus(short);
     method public void setSubmessageId(short);
+    method public void setSvid(short);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
@@ -20590,8 +20596,8 @@
     method public int getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
-    method public int getPrn(int);
     method public float getSnr(int);
+    method public int getSvid(int);
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
@@ -21082,6 +21088,7 @@
   public final class AudioAttributes implements android.os.Parcelable {
     method public int describeContents();
     method public int getAllFlags();
+    method public android.os.Bundle getBundle();
     method public int getCapturePreset();
     method public int getContentType();
     method public int getFlags();
@@ -21120,6 +21127,7 @@
   public static class AudioAttributes.Builder {
     ctor public AudioAttributes.Builder();
     ctor public AudioAttributes.Builder(android.media.AudioAttributes);
+    method public android.media.AudioAttributes.Builder addBundle(android.os.Bundle);
     method public android.media.AudioAttributes build();
     method public android.media.AudioAttributes.Builder setCapturePreset(int);
     method public android.media.AudioAttributes.Builder setContentType(int);
@@ -24273,19 +24281,26 @@
 package android.media.soundtrigger {
 
   public final class SoundTriggerDetector {
-    method public boolean startRecognition();
+    method public boolean startRecognition(int);
     method public boolean stopRecognition();
+    field public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 2; // 0x2
+    field public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 1; // 0x1
   }
 
-  public abstract class SoundTriggerDetector.Callback {
+  public static abstract class SoundTriggerDetector.Callback {
     ctor public SoundTriggerDetector.Callback();
     method public abstract void onAvailabilityChanged(int);
-    method public abstract void onDetected();
+    method public abstract void onDetected(android.media.soundtrigger.SoundTriggerDetector.EventPayload);
     method public abstract void onError();
     method public abstract void onRecognitionPaused();
     method public abstract void onRecognitionResumed();
   }
 
+  public static class SoundTriggerDetector.EventPayload {
+    method public android.media.AudioFormat getCaptureAudioFormat();
+    method public byte[] getTriggerAudio();
+  }
+
   public final class SoundTriggerManager {
     method public android.media.soundtrigger.SoundTriggerDetector createSoundTriggerDetector(java.util.UUID, android.media.soundtrigger.SoundTriggerDetector.Callback, android.os.Handler);
     method public void deleteModel(java.util.UUID);
@@ -24488,6 +24503,7 @@
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -24644,9 +24660,8 @@
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
     field public static final java.lang.String META_DATA_CONTENT_RATING_SYSTEMS = "android.media.tv.metadata.CONTENT_RATING_SYSTEMS";
-    field public static final int RECORDING_ERROR_CONNECTION_FAILED = 1; // 0x1
-    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 2; // 0x2
-    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 3; // 0x3
+    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1; // 0x1
+    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 2; // 0x2
     field public static final int RECORDING_ERROR_UNKNOWN = 0; // 0x0
     field public static final long TIME_SHIFT_INVALID_TIME = -9223372036854775808L; // 0x8000000000000000L
     field public static final int TIME_SHIFT_STATUS_AVAILABLE = 3; // 0x3
@@ -24712,7 +24727,7 @@
     method public void onInputRemoved(java.lang.String);
     method public void onInputStateChanged(java.lang.String, int);
     method public void onInputUpdated(java.lang.String);
-    method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
+    method public void onTvInputInfoUpdated(android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
@@ -24724,7 +24739,7 @@
     method public java.lang.String onHardwareRemoved(android.media.tv.TvInputHardwareInfo);
     method public android.media.tv.TvInputInfo onHdmiDeviceAdded(android.hardware.hdmi.HdmiDeviceInfo);
     method public java.lang.String onHdmiDeviceRemoved(android.hardware.hdmi.HdmiDeviceInfo);
-    method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
+    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -24739,17 +24754,16 @@
 
   public static abstract class TvInputService.RecordingSession {
     ctor public TvInputService.RecordingSession(android.content.Context);
-    method public void notifyConnected();
     method public void notifyError(int);
-    method public void notifyRecordingStarted();
     method public void notifyRecordingStopped(android.net.Uri);
     method public void notifySessionEvent(java.lang.String, android.os.Bundle);
+    method public void notifyTuned();
     method public void onAppPrivateCommand(java.lang.String, android.os.Bundle);
-    method public abstract void onConnect(android.net.Uri);
-    method public void onConnect(android.net.Uri, android.os.Bundle);
-    method public abstract void onDisconnect();
-    method public abstract void onStartRecording();
+    method public abstract void onRelease();
+    method public abstract void onStartRecording(android.net.Uri);
     method public abstract void onStopRecording();
+    method public abstract void onTune(android.net.Uri);
+    method public void onTune(android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
@@ -24796,22 +24810,22 @@
 
   public class TvRecordingClient {
     ctor public TvRecordingClient(android.content.Context, java.lang.String, android.media.tv.TvRecordingClient.RecordingCallback, android.os.Handler);
-    method public void connect(java.lang.String, android.net.Uri);
-    method public void connect(java.lang.String, android.net.Uri, android.os.Bundle);
-    method public void disconnect();
+    method public void release();
     method public void sendAppPrivateCommand(java.lang.String, android.os.Bundle);
-    method public void startRecording();
+    method public void startRecording(android.net.Uri);
     method public void stopRecording();
+    method public void tune(java.lang.String, android.net.Uri);
+    method public void tune(java.lang.String, android.net.Uri, android.os.Bundle);
   }
 
   public static abstract class TvRecordingClient.RecordingCallback {
     ctor public TvRecordingClient.RecordingCallback();
-    method public void onConnected();
-    method public void onDisconnected();
+    method public void onConnectionFailed(java.lang.String);
+    method public void onDisconnected(java.lang.String);
     method public void onError(int);
     method public void onEvent(java.lang.String, java.lang.String, android.os.Bundle);
-    method public void onRecordingStarted();
     method public void onRecordingStopped(android.net.Uri);
+    method public void onTuned();
   }
 
   public class TvStreamConfig implements android.os.Parcelable {
@@ -24849,6 +24863,7 @@
     method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
     method public final int getType();
+    method public final byte getVideoActiveFormatDescription();
     method public final float getVideoFrameRate();
     method public final int getVideoHeight();
     method public final float getVideoPixelAspectRatio();
@@ -24868,6 +24883,7 @@
     method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.CharSequence);
     method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
     method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoActiveFormatDescription(byte);
     method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
     method public final android.media.tv.TvTrackInfo.Builder setVideoHeight(int);
     method public final android.media.tv.TvTrackInfo.Builder setVideoPixelAspectRatio(float);
@@ -26233,12 +26249,18 @@
   }
 
   public class RttManager {
+    method public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
+    method public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
     method public deprecated android.net.wifi.RttManager.Capabilities getCapabilities();
     method public android.net.wifi.RttManager.RttCapabilities getRttCapabilities();
     method public void startRanging(android.net.wifi.RttManager.RttParams[], android.net.wifi.RttManager.RttListener);
     method public void stopRanging(android.net.wifi.RttManager.RttListener);
     field public static final int BASE = 160256; // 0x27200
     field public static final int CMD_OP_ABORTED = 160260; // 0x27204
+    field public static final int CMD_OP_DISABLE_RESPONDER = 160262; // 0x27206
+    field public static final int CMD_OP_ENABLE_RESPONDER = 160261; // 0x27205
+    field public static final int CMD_OP_ENALBE_RESPONDER_FAILED = 160264; // 0x27208
+    field public static final int CMD_OP_ENALBE_RESPONDER_SUCCEEDED = 160263; // 0x27207
     field public static final int CMD_OP_FAILED = 160258; // 0x27202
     field public static final int CMD_OP_START_RANGING = 160256; // 0x27200
     field public static final int CMD_OP_STOP_RANGING = 160257; // 0x27201
@@ -26247,6 +26269,7 @@
     field public static final int PREAMBLE_HT = 2; // 0x2
     field public static final int PREAMBLE_LEGACY = 1; // 0x1
     field public static final int PREAMBLE_VHT = 4; // 0x4
+    field public static final int REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON = -6; // 0xfffffffa
     field public static final int REASON_INVALID_LISTENER = -3; // 0xfffffffd
     field public static final int REASON_INVALID_REQUEST = -4; // 0xfffffffc
     field public static final int REASON_NOT_AVAILABLE = -2; // 0xfffffffe
@@ -26314,6 +26337,25 @@
     field public android.net.wifi.RttManager.RttResult[] mResults;
   }
 
+  public static abstract class RttManager.ResponderCallback {
+    ctor public RttManager.ResponderCallback();
+    method public abstract void onResponderEnableFailure(int);
+    method public abstract void onResponderEnabled(android.net.wifi.RttManager.ResponderConfig);
+  }
+
+  public static class RttManager.ResponderConfig implements android.os.Parcelable {
+    ctor public RttManager.ResponderConfig();
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.RttManager.ResponderConfig> CREATOR;
+    field public int centerFreq0;
+    field public int centerFreq1;
+    field public int channelWidth;
+    field public int frequency;
+    field public java.lang.String macAddress;
+    field public int preamble;
+  }
+
   public static class RttManager.RttCapabilities implements android.os.Parcelable {
     ctor public RttManager.RttCapabilities();
     method public int describeContents();
@@ -26323,6 +26365,7 @@
     field public boolean lcrSupported;
     field public boolean oneSidedRttSupported;
     field public int preambleSupported;
+    field public boolean responderSupported;
     field public deprecated boolean supportedPeerType;
     field public deprecated boolean supportedType;
     field public boolean twoSided11McRttSupported;
@@ -26650,6 +26693,7 @@
     method public boolean reconnect();
     method public boolean removeNetwork(int);
     method public boolean saveConfiguration();
+    method public boolean setMetered(int, boolean);
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
     method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
@@ -26769,7 +26813,6 @@
     field public static final int REASON_UNSPECIFIED = -1; // 0xffffffff
     field public static final deprecated int REPORT_EVENT_AFTER_BUFFER_FULL = 0; // 0x0
     field public static final int REPORT_EVENT_AFTER_EACH_SCAN = 1; // 0x1
-    field public static final int REPORT_EVENT_CONTEXT_HUB = 8; // 0x8
     field public static final int REPORT_EVENT_FULL_SCAN_RESULT = 2; // 0x2
     field public static final int REPORT_EVENT_NO_BATCH = 4; // 0x4
     field public static final int WIFI_BAND_24_GHZ = 1; // 0x1
@@ -30821,7 +30864,6 @@
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
-    field public static java.lang.String DIRECTORY_HOME;
     field public static java.lang.String DIRECTORY_MOVIES;
     field public static java.lang.String DIRECTORY_MUSIC;
     field public static java.lang.String DIRECTORY_NOTIFICATIONS;
@@ -31325,6 +31367,7 @@
     method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
     method public static final int getUidForName(java.lang.String);
     method public static final boolean is64Bit();
+    method public static boolean isApplicationUid(int);
     method public static final void killProcess(int);
     method public static final int myPid();
     method public static final int myTid();
@@ -31502,10 +31545,56 @@
     ctor public TransactionTooLargeException(java.lang.String);
   }
 
+  public class UpdateEngine {
+    ctor public UpdateEngine();
+    method public void applyPayload(java.lang.String, long, long, java.lang.String[]) throws android.os.RemoteException;
+    method public boolean bind(android.os.UpdateEngineCallback, android.os.Handler) throws android.os.RemoteException;
+    method public boolean bind(android.os.UpdateEngineCallback) throws android.os.RemoteException;
+    method public void cancel() throws android.os.RemoteException;
+    method public void resume() throws android.os.RemoteException;
+    method public void suspend() throws android.os.RemoteException;
+  }
+
+  public static final class UpdateEngine.ErrorCodeConstants {
+    ctor public UpdateEngine.ErrorCodeConstants();
+    field public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12; // 0xc
+    field public static final int DOWNLOAD_TRANSFER_ERROR = 9; // 0x9
+    field public static final int ERROR = 1; // 0x1
+    field public static final int FILESYSTEM_COPIER_ERROR = 4; // 0x4
+    field public static final int INSTALL_DEVICE_OPEN_ERROR = 7; // 0x7
+    field public static final int KERNEL_DEVICE_OPEN_ERROR = 8; // 0x8
+    field public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10; // 0xa
+    field public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6; // 0x6
+    field public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11; // 0xb
+    field public static final int POST_INSTALL_RUNNER_ERROR = 5; // 0x5
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static final class UpdateEngine.UpdateStatusConstants {
+    ctor public UpdateEngine.UpdateStatusConstants();
+    field public static final int ATTEMPTING_ROLLBACK = 8; // 0x8
+    field public static final int CHECKING_FOR_UPDATE = 1; // 0x1
+    field public static final int DISABLED = 9; // 0x9
+    field public static final int DOWNLOADING = 3; // 0x3
+    field public static final int FINALIZING = 5; // 0x5
+    field public static final int IDLE = 0; // 0x0
+    field public static final int REPORTING_ERROR_EVENT = 7; // 0x7
+    field public static final int UPDATED_NEED_REBOOT = 6; // 0x6
+    field public static final int UPDATE_AVAILABLE = 2; // 0x2
+    field public static final int VERIFYING = 4; // 0x4
+  }
+
+  public abstract class UpdateEngineCallback {
+    ctor public UpdateEngineCallback();
+    method public abstract void onPayloadApplicationComplete(int);
+    method public abstract void onStatusUpdate(int, float);
+  }
+
   public final class UserHandle implements android.os.Parcelable {
     ctor public UserHandle(android.os.Parcel);
     method public int describeContents();
     method public int getIdentifier();
+    method public static android.os.UserHandle getUserHandleForUid(int);
     method public deprecated boolean isOwner();
     method public boolean isSystem();
     method public static int myUserId();
@@ -31629,11 +31718,27 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
   }
 
+  public class StorageVolume implements android.os.Parcelable {
+    method public android.content.Intent createAccessIntent(java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getDescription(android.content.Context);
+    method public java.lang.String getState();
+    method public java.lang.String getUuid();
+    method public boolean isEmulated();
+    method public boolean isPrimary();
+    method public boolean isRemovable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.storage.StorageVolume> CREATOR;
+    field public static final java.lang.String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME";
+  }
+
 }
 
 package android.preference {
@@ -33764,6 +33869,8 @@
   }
 
   protected static abstract interface ContactsContract.PhoneLookupColumns {
+    field public static final java.lang.String CONTACT_ID = "contact_id";
+    field public static final java.lang.String DATA_ID = "data_id";
     field public static final java.lang.String LABEL = "label";
     field public static final java.lang.String NORMALIZED_NUMBER = "normalized_number";
     field public static final java.lang.String NUMBER = "number";
@@ -34027,6 +34134,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
@@ -34047,7 +34155,7 @@
     method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
     method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
-    method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public void removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final void revokeDocumentPermission(java.lang.String);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
@@ -34549,6 +34657,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_SCREEN_READER_TUTORIAL = "android.settings.SCREEN_READER_TUTORIAL";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -34609,6 +34718,7 @@
     field public static final deprecated java.lang.String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
     field public static final java.lang.String MODE_RINGER = "mode_ringer";
     field public static final java.lang.String NETWORK_PREFERENCE = "network_preference";
+    field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
     field public static final java.lang.String RADIO_BLUETOOTH = "bluetooth";
     field public static final java.lang.String RADIO_CELL = "cell";
     field public static final java.lang.String RADIO_NFC = "nfc";
@@ -36454,6 +36564,7 @@
 
   public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+    method public byte[] getAttestationChallenge();
     method public java.lang.String[] getBlockModes();
     method public java.util.Date getCertificateNotAfter();
     method public java.util.Date getCertificateNotBefore();
@@ -36478,6 +36589,7 @@
     ctor public KeyGenParameterSpec.Builder(java.lang.String, int);
     method public android.security.keystore.KeyGenParameterSpec build();
     method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+    method public android.security.keystore.KeyGenParameterSpec.Builder setAttestationChallenge(byte[]);
     method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date);
@@ -40455,6 +40567,7 @@
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public void grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -43339,6 +43452,21 @@
     method public static android.view.FocusFinder getInstance();
   }
 
+  public final class FrameMetrics {
+    ctor public FrameMetrics(android.view.FrameMetrics);
+    method public long getMetric(int);
+    field public static final int ANIMATION_DURATION = 2; // 0x2
+    field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6
+    field public static final int DRAW_DURATION = 4; // 0x4
+    field public static final int FIRST_DRAW_FRAME = 9; // 0x9
+    field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
+    field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
+    field public static final int SYNC_DURATION = 5; // 0x5
+    field public static final int TOTAL_DURATION = 8; // 0x8
+    field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+  }
+
   public abstract class FrameStats {
     ctor public FrameStats();
     method public final long getEndTimeNano();
@@ -45842,6 +45970,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
+    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -45893,6 +46022,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
+    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -46019,6 +46149,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.FrameMetricsListener {
+    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  }
+
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
     method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
   }
@@ -54464,7 +54598,6 @@
     method public static int getLength(java.lang.Object);
     method public static long getLong(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
     method public static short getShort(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static java.lang.Object newArray(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int...) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException;
     method public static void set(java.lang.Object, int, java.lang.Object) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
@@ -55140,7 +55273,6 @@
 
   public class InetAddress implements java.io.Serializable {
     method public byte[] getAddress();
-    method public byte[] getAddressInternal();
     method public static java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(java.lang.String, byte[]) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(byte[]) throws java.net.UnknownHostException;
@@ -55414,7 +55546,7 @@
     method protected abstract void connect(java.net.InetAddress, int) throws java.io.IOException;
     method protected abstract void connect(java.net.SocketAddress, int) throws java.io.IOException;
     method protected abstract void create(boolean) throws java.io.IOException;
-    method public java.io.FileDescriptor getFileDescriptor();
+    method protected java.io.FileDescriptor getFileDescriptor();
     method protected java.net.InetAddress getInetAddress();
     method protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
     method protected int getLocalPort();
@@ -55956,10 +56088,6 @@
 
 package java.nio.channels {
 
-  public class AcceptPendingException extends java.lang.IllegalStateException {
-    ctor public AcceptPendingException();
-  }
-
   public class AlreadyBoundException extends java.lang.IllegalStateException {
     ctor public AlreadyBoundException();
   }
@@ -55968,68 +56096,10 @@
     ctor public AlreadyConnectedException();
   }
 
-  public abstract interface AsynchronousByteChannel implements java.nio.channels.AsynchronousChannel {
-    method public abstract void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-  }
-
-  public abstract interface AsynchronousChannel implements java.nio.channels.Channel {
-    method public abstract void close() throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousChannelGroup {
-    ctor protected AsynchronousChannelGroup(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract boolean isShutdown();
-    method public abstract boolean isTerminated();
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void shutdown();
-    method public abstract void shutdownNow() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withCachedThreadPool(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withFixedThreadPool(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withThreadPool(java.util.concurrent.ExecutorService) throws java.io.IOException;
-  }
-
   public class AsynchronousCloseException extends java.nio.channels.ClosedChannelException {
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousServerSocketChannel implements java.nio.channels.AsynchronousChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousServerSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract void accept(A, java.nio.channels.CompletionHandler<java.nio.channels.AsynchronousSocketChannel, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.AsynchronousSocketChannel> accept();
-    method public final java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousSocketChannel implements java.nio.channels.AsynchronousByteChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract java.nio.channels.AsynchronousSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract void connect(java.net.SocketAddress, A, java.nio.channels.CompletionHandler<java.lang.Void, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Void> connect(java.net.SocketAddress);
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void read(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void read(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-    method public abstract java.nio.channels.AsynchronousSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownInput() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownOutput() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-  }
-
   public abstract interface ByteChannel implements java.nio.channels.ReadableByteChannel java.nio.channels.WritableByteChannel {
   }
 
@@ -56046,9 +56116,7 @@
     method public static java.nio.channels.ReadableByteChannel newChannel(java.io.InputStream);
     method public static java.nio.channels.WritableByteChannel newChannel(java.io.OutputStream);
     method public static java.io.InputStream newInputStream(java.nio.channels.ReadableByteChannel);
-    method public static java.io.InputStream newInputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.OutputStream newOutputStream(java.nio.channels.WritableByteChannel);
-    method public static java.io.OutputStream newOutputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.lang.String);
     method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int);
@@ -56067,16 +56135,11 @@
     ctor public ClosedSelectorException();
   }
 
-  public abstract interface CompletionHandler {
-    method public abstract void completed(V, A);
-    method public abstract void failed(java.lang.Throwable, A);
-  }
-
   public class ConnectionPendingException extends java.lang.IllegalStateException {
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
@@ -56155,40 +56218,14 @@
     ctor public IllegalBlockingModeException();
   }
 
-  public class IllegalChannelGroupException extends java.lang.IllegalArgumentException {
-    ctor public IllegalChannelGroupException();
-  }
-
   public class IllegalSelectorException extends java.lang.IllegalArgumentException {
     ctor public IllegalSelectorException();
   }
 
-  public class InterruptedByTimeoutException extends java.io.IOException {
-    ctor public InterruptedByTimeoutException();
-  }
-
   public abstract interface InterruptibleChannel implements java.nio.channels.Channel {
     method public abstract void close() throws java.io.IOException;
   }
 
-  public abstract class MembershipKey {
-    ctor protected MembershipKey();
-    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.MulticastChannel channel();
-    method public abstract void drop();
-    method public abstract java.net.InetAddress group();
-    method public abstract boolean isValid();
-    method public abstract java.net.NetworkInterface networkInterface();
-    method public abstract java.net.InetAddress sourceAddress();
-    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
-  }
-
-  public abstract interface MulticastChannel implements java.nio.channels.NetworkChannel {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
-  }
-
   public abstract interface NetworkChannel implements java.nio.channels.Channel {
     method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
@@ -56238,10 +56275,6 @@
     method public final int validOps();
   }
 
-  public class ReadPendingException extends java.lang.IllegalStateException {
-    ctor public ReadPendingException();
-  }
-
   public abstract interface ReadableByteChannel implements java.nio.channels.Channel {
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
   }
@@ -56319,10 +56352,6 @@
     method public final int validOps();
   }
 
-  public class ShutdownChannelGroupException extends java.lang.IllegalStateException {
-    ctor public ShutdownChannelGroupException();
-  }
-
   public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
@@ -56358,10 +56387,6 @@
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
   }
 
-  public class WritePendingException extends java.lang.IllegalStateException {
-    ctor public WritePendingException();
-  }
-
 }
 
 package java.nio.channels.spi {
@@ -56408,15 +56433,6 @@
     method protected abstract java.nio.channels.SelectionKey register(java.nio.channels.spi.AbstractSelectableChannel, int, java.lang.Object);
   }
 
-  public abstract class AsynchronousChannelProvider {
-    ctor protected AsynchronousChannelProvider();
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel openAsynchronousSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.spi.AsynchronousChannelProvider provider();
-  }
-
   public abstract class SelectorProvider {
     ctor protected SelectorProvider();
     method public java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
@@ -57231,7 +57247,6 @@
   public abstract class Signature extends java.security.SignatureSpi {
     ctor protected Signature(java.lang.String);
     method public final java.lang.String getAlgorithm();
-    method public java.security.SignatureSpi getCurrentSpi();
     method public static java.security.Signature getInstance(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public static java.security.Signature getInstance(java.lang.String, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
     method public static java.security.Signature getInstance(java.lang.String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
@@ -59771,13 +59786,11 @@
     method public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale);
     method public java.lang.String getInternationalCurrencySymbol();
     method public char getMinusSign();
-    method public java.lang.String getMinusSignString();
     method public char getMonetaryDecimalSeparator();
     method public java.lang.String getNaN();
     method public char getPatternSeparator();
     method public char getPerMill();
     method public char getPercent();
-    method public java.lang.String getPercentString();
     method public char getZeroDigit();
     method public void setCurrency(java.util.Currency);
     method public void setCurrencySymbol(java.lang.String);
@@ -61030,8 +61043,11 @@
     method public static boolean equals(java.lang.Object, java.lang.Object);
     method public static int hash(java.lang.Object...);
     method public static int hashCode(java.lang.Object);
+    method public static boolean isNull(java.lang.Object);
+    method public static boolean nonNull(java.lang.Object);
     method public static T requireNonNull(T);
     method public static T requireNonNull(T, java.lang.String);
+    method public static T requireNonNull(T, java.util.function.Supplier<java.lang.String>);
     method public static java.lang.String toString(java.lang.Object);
     method public static java.lang.String toString(java.lang.Object, java.lang.String);
   }
@@ -62736,6 +62752,217 @@
 
 }
 
+package java.util.function {
+
+  public abstract interface BiConsumer {
+    method public abstract void accept(T, U);
+    method public default java.util.function.BiConsumer<T, U> andThen(java.util.function.BiConsumer<? super T, ? super U>);
+  }
+
+  public abstract interface BiFunction {
+    method public default java.util.function.BiFunction<T, U, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T, U);
+  }
+
+  public abstract interface BiPredicate {
+    method public default java.util.function.BiPredicate<T, U> and(java.util.function.BiPredicate<? super T, ? super U>);
+    method public default java.util.function.BiPredicate<T, U> negate();
+    method public default java.util.function.BiPredicate<T, U> or(java.util.function.BiPredicate<? super T, ? super U>);
+    method public abstract boolean test(T, U);
+  }
+
+  public abstract interface BinaryOperator implements java.util.function.BiFunction {
+    method public static java.util.function.BinaryOperator<T> maxBy(java.util.Comparator<? super T>);
+    method public static java.util.function.BinaryOperator<T> minBy(java.util.Comparator<? super T>);
+  }
+
+  public abstract interface BooleanSupplier {
+    method public abstract boolean getAsBoolean();
+  }
+
+  public abstract interface Consumer {
+    method public abstract void accept(T);
+    method public default java.util.function.Consumer<T> andThen(java.util.function.Consumer<? super T>);
+  }
+
+  public abstract interface DoubleBinaryOperator {
+    method public abstract double applyAsDouble(double, double);
+  }
+
+  public abstract interface DoubleConsumer {
+    method public abstract void accept(double);
+    method public default java.util.function.DoubleConsumer andThen(java.util.function.DoubleConsumer);
+  }
+
+  public abstract interface DoubleFunction {
+    method public abstract R apply(double);
+  }
+
+  public abstract interface DoublePredicate {
+    method public default java.util.function.DoublePredicate and(java.util.function.DoublePredicate);
+    method public default java.util.function.DoublePredicate negate();
+    method public default java.util.function.DoublePredicate or(java.util.function.DoublePredicate);
+    method public abstract boolean test(double);
+  }
+
+  public abstract interface DoubleSupplier {
+    method public abstract double getAsDouble();
+  }
+
+  public abstract interface DoubleToIntFunction {
+    method public abstract int applyAsInt(double);
+  }
+
+  public abstract interface DoubleToLongFunction {
+    method public abstract long applyAsLong(double);
+  }
+
+  public abstract interface DoubleUnaryOperator {
+    method public default java.util.function.DoubleUnaryOperator andThen(java.util.function.DoubleUnaryOperator);
+    method public abstract double applyAsDouble(double);
+    method public default java.util.function.DoubleUnaryOperator compose(java.util.function.DoubleUnaryOperator);
+    method public static java.util.function.DoubleUnaryOperator identity();
+  }
+
+  public abstract interface Function {
+    method public default java.util.function.Function<T, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T);
+    method public default java.util.function.Function<V, R> compose(java.util.function.Function<? super V, ? extends T>);
+    method public static java.util.function.Function<T, T> identity();
+  }
+
+  public abstract interface IntBinaryOperator {
+    method public abstract int applyAsInt(int, int);
+  }
+
+  public abstract interface IntConsumer {
+    method public abstract void accept(int);
+    method public default java.util.function.IntConsumer andThen(java.util.function.IntConsumer);
+  }
+
+  public abstract interface IntFunction {
+    method public abstract R apply(int);
+  }
+
+  public abstract interface IntPredicate {
+    method public default java.util.function.IntPredicate and(java.util.function.IntPredicate);
+    method public default java.util.function.IntPredicate negate();
+    method public default java.util.function.IntPredicate or(java.util.function.IntPredicate);
+    method public abstract boolean test(int);
+  }
+
+  public abstract interface IntSupplier {
+    method public abstract int getAsInt();
+  }
+
+  public abstract interface IntToDoubleFunction {
+    method public abstract double applyAsDouble(int);
+  }
+
+  public abstract interface IntToLongFunction {
+    method public abstract long applyAsLong(int);
+  }
+
+  public abstract interface IntUnaryOperator {
+    method public default java.util.function.IntUnaryOperator andThen(java.util.function.IntUnaryOperator);
+    method public abstract int applyAsInt(int);
+    method public default java.util.function.IntUnaryOperator compose(java.util.function.IntUnaryOperator);
+    method public static java.util.function.IntUnaryOperator identity();
+  }
+
+  public abstract interface LongBinaryOperator {
+    method public abstract long applyAsLong(long, long);
+  }
+
+  public abstract interface LongConsumer {
+    method public abstract void accept(long);
+    method public default java.util.function.LongConsumer andThen(java.util.function.LongConsumer);
+  }
+
+  public abstract interface LongFunction {
+    method public abstract R apply(long);
+  }
+
+  public abstract interface LongPredicate {
+    method public default java.util.function.LongPredicate and(java.util.function.LongPredicate);
+    method public default java.util.function.LongPredicate negate();
+    method public default java.util.function.LongPredicate or(java.util.function.LongPredicate);
+    method public abstract boolean test(long);
+  }
+
+  public abstract interface LongSupplier {
+    method public abstract long getAsLong();
+  }
+
+  public abstract interface LongToDoubleFunction {
+    method public abstract double applyAsDouble(long);
+  }
+
+  public abstract interface LongToIntFunction {
+    method public abstract int applyAsInt(long);
+  }
+
+  public abstract interface LongUnaryOperator {
+    method public default java.util.function.LongUnaryOperator andThen(java.util.function.LongUnaryOperator);
+    method public abstract long applyAsLong(long);
+    method public default java.util.function.LongUnaryOperator compose(java.util.function.LongUnaryOperator);
+    method public static java.util.function.LongUnaryOperator identity();
+  }
+
+  public abstract interface ObjDoubleConsumer {
+    method public abstract void accept(T, double);
+  }
+
+  public abstract interface ObjIntConsumer {
+    method public abstract void accept(T, int);
+  }
+
+  public abstract interface ObjLongConsumer {
+    method public abstract void accept(T, long);
+  }
+
+  public abstract interface Predicate {
+    method public default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T>);
+    method public static java.util.function.Predicate<T> isEqual(java.lang.Object);
+    method public default java.util.function.Predicate<T> negate();
+    method public default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T>);
+    method public abstract boolean test(T);
+  }
+
+  public abstract interface Supplier {
+    method public abstract T get();
+  }
+
+  public abstract interface ToDoubleBiFunction {
+    method public abstract double applyAsDouble(T, U);
+  }
+
+  public abstract interface ToDoubleFunction {
+    method public abstract double applyAsDouble(T);
+  }
+
+  public abstract interface ToIntBiFunction {
+    method public abstract int applyAsInt(T, U);
+  }
+
+  public abstract interface ToIntFunction {
+    method public abstract int applyAsInt(T);
+  }
+
+  public abstract interface ToLongBiFunction {
+    method public abstract long applyAsLong(T, U);
+  }
+
+  public abstract interface ToLongFunction {
+    method public abstract long applyAsLong(T);
+  }
+
+  public abstract interface UnaryOperator implements java.util.function.Function {
+    method public static java.util.function.UnaryOperator<T> identity();
+  }
+
+}
+
 package java.util.jar {
 
   public class Attributes implements java.lang.Cloneable java.util.Map {
@@ -65470,14 +65697,6 @@
     method public abstract boolean isDestroyed();
   }
 
-  public abstract deprecated class Policy {
-    ctor protected Policy();
-    method public abstract java.security.PermissionCollection getPermissions(javax.security.auth.Subject, java.security.CodeSource);
-    method public static javax.security.auth.Policy getPolicy();
-    method public abstract void refresh();
-    method public static void setPolicy(javax.security.auth.Policy);
-  }
-
   public final class PrivateCredentialPermission extends java.security.Permission {
     ctor public PrivateCredentialPermission(java.lang.String, java.lang.String);
     method public boolean equals(java.lang.Object);
@@ -65542,43 +65761,6 @@
 
 package javax.security.auth.login {
 
-  public class AppConfigurationEntry {
-    ctor public AppConfigurationEntry(java.lang.String, javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag, java.util.Map<java.lang.String, ?>);
-    method public javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag getControlFlag();
-    method public java.lang.String getLoginModuleName();
-    method public java.util.Map<java.lang.String, ?> getOptions();
-  }
-
-  public static class AppConfigurationEntry.LoginModuleControlFlag {
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag OPTIONAL;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUIRED;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUISITE;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag SUFFICIENT;
-  }
-
-  public abstract class Configuration {
-    ctor protected Configuration();
-    method public abstract javax.security.auth.login.AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String);
-    method public static javax.security.auth.login.Configuration getConfiguration();
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters) throws java.security.NoSuchAlgorithmException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public javax.security.auth.login.Configuration.Parameters getParameters();
-    method public java.security.Provider getProvider();
-    method public java.lang.String getType();
-    method public void refresh();
-    method public static void setConfiguration(javax.security.auth.login.Configuration);
-  }
-
-  public static abstract interface Configuration.Parameters {
-  }
-
-  public abstract class ConfigurationSpi {
-    ctor public ConfigurationSpi();
-    method protected abstract javax.security.auth.login.AppConfigurationEntry[] engineGetAppConfigurationEntry(java.lang.String);
-    method protected void engineRefresh();
-  }
-
   public class LoginException extends java.security.GeneralSecurityException {
     ctor public LoginException();
     ctor public LoginException(java.lang.String);
diff --git a/api/test-current.txt b/api/test-current.txt
index c1cd275..d42c18c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -104,6 +104,7 @@
     field public static final java.lang.String READ_WRITE_CONTACT_METADATA = "android.permission.READ_WRITE_CONTACT_METADATA";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
+    field public static final java.lang.String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST";
     field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
     field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
     field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
@@ -197,7 +198,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int abiOverride = 16844054; // 0x1010516
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
     field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -1364,6 +1364,7 @@
     field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344
     field public static final int unselectedAlpha = 16843278; // 0x101020e
     field public static final int updatePeriodMillis = 16843344; // 0x1010250
+    field public static final int use32bitAbi = 16844054; // 0x1010516
     field public static final int useDefaultMargins = 16843641; // 0x1010379
     field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
     field public static final int useLevel = 16843167; // 0x101019f
@@ -1375,6 +1376,7 @@
     field public static final int valueType = 16843488; // 0x10102e0
     field public static final int variablePadding = 16843157; // 0x1010195
     field public static final int vendor = 16843751; // 0x10103e7
+    field public static final int version = 16844058; // 0x101051a
     field public static final int versionCode = 16843291; // 0x101021b
     field public static final int versionName = 16843292; // 0x101021c
     field public static final int verticalCorrection = 16843322; // 0x101023a
@@ -4273,6 +4275,7 @@
 
   public class DownloadManager {
     method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean);
+    method public long addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean, android.net.Uri, android.net.Uri);
     method public long enqueue(android.app.DownloadManager.Request);
     method public static java.lang.Long getMaxBytesOverMobile(android.content.Context);
     method public java.lang.String getMimeTypeForDownloadedFile(long);
@@ -5224,6 +5227,7 @@
 
   public class NotificationManager {
     method public android.app.AutomaticZenRule addAutomaticZenRule(android.app.AutomaticZenRule);
+    method public boolean areNotificationsEnabled();
     method public void cancel(int);
     method public void cancel(java.lang.String, int);
     method public void cancelAll();
@@ -5231,6 +5235,7 @@
     method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
     method public java.util.List<android.app.AutomaticZenRule> getAutomaticZenRules();
     method public final int getCurrentInterruptionFilter();
+    method public int getImportance(java.lang.String);
     method public android.app.NotificationManager.Policy getNotificationPolicy();
     method public boolean isNotificationPolicyAccessGranted();
     method public void notify(int, android.app.Notification);
@@ -5927,7 +5932,7 @@
     method public void setMaximumTimeToLock(android.content.ComponentName, long);
     method public void setOrganizationColor(android.content.ComponentName, int);
     method public void setOrganizationName(android.content.ComponentName, java.lang.String);
-    method public boolean setPackageSuspended(android.content.ComponentName, java.lang.String, boolean);
+    method public java.lang.String[] setPackagesSuspended(android.content.ComponentName, java.lang.String[], boolean);
     method public void setPasswordExpirationTimeout(android.content.ComponentName, long);
     method public void setPasswordHistoryLength(android.content.ComponentName, int);
     method public void setPasswordMinimumLength(android.content.ComponentName, int);
@@ -8514,6 +8519,7 @@
     field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED";
     field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED";
+    field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED";
     field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
     field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
     field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
@@ -8533,7 +8539,6 @@
     field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
     field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
-    field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
     field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
     field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
     field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -9403,6 +9408,7 @@
     field public int flags;
     field public java.lang.String name;
     field public int reqGlEsVersion;
+    field public int version;
   }
 
   public class InstrumentationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -9682,6 +9688,7 @@
     method public abstract java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public abstract android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public abstract boolean hasSystemFeature(java.lang.String);
+    method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -19226,7 +19233,6 @@
     method public double getElevationUncertaintyInDeg();
     method public byte getLossOfLock();
     method public byte getMultipathIndicator();
-    method public byte getPrn();
     method public double getPseudorangeInMeters();
     method public double getPseudorangeRateCarrierInMetersPerSec();
     method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec();
@@ -19237,6 +19243,7 @@
     method public long getReceivedGpsTowUncertaintyInNs();
     method public double getSnrInDb();
     method public short getState();
+    method public short getSvid();
     method public short getTimeFromLastBitInMs();
     method public double getTimeOffsetInNs();
     method public boolean hasAzimuthInDeg();
@@ -19296,7 +19303,6 @@
     method public void setElevationUncertaintyInDeg(double);
     method public void setLossOfLock(byte);
     method public void setMultipathIndicator(byte);
-    method public void setPrn(byte);
     method public void setPseudorangeInMeters(double);
     method public void setPseudorangeRateCarrierInMetersPerSec(double);
     method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double);
@@ -19307,6 +19313,7 @@
     method public void setReceivedGpsTowUncertaintyInNs(long);
     method public void setSnrInDb(double);
     method public void setState(short);
+    method public void setSvid(short);
     method public void setTimeFromLastBitInMs(short);
     method public void setTimeOffsetInNs(double);
     method public void setUsedInFix(boolean);
@@ -19361,17 +19368,17 @@
     method public int describeContents();
     method public byte[] getData();
     method public short getMessageId();
-    method public byte getPrn();
     method public short getStatus();
     method public short getSubmessageId();
+    method public short getSvid();
     method public byte getType();
     method public void reset();
     method public void set(android.location.GnssNavigationMessage);
     method public void setData(byte[]);
     method public void setMessageId(short);
-    method public void setPrn(byte);
     method public void setStatus(short);
     method public void setSubmessageId(short);
+    method public void setSvid(short);
     method public void setType(byte);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR;
@@ -19417,8 +19424,8 @@
     method public int getConstellationType(int);
     method public float getElevation(int);
     method public int getNumSatellites();
-    method public int getPrn(int);
     method public float getSnr(int);
+    method public int getSvid(int);
     method public boolean hasAlmanac(int);
     method public boolean hasEphemeris(int);
     method public boolean usedInFix(int);
@@ -22880,6 +22887,7 @@
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
@@ -22915,7 +22923,9 @@
     method public android.content.pm.ServiceInfo getServiceInfo();
     method public int getTunerCount();
     method public int getType();
+    method public boolean isHidden(android.content.Context);
     method public boolean isPassthroughInput();
+    method public java.lang.CharSequence loadCustomLabel(android.content.Context);
     method public android.graphics.drawable.Drawable loadIcon(android.content.Context);
     method public java.lang.CharSequence loadLabel(android.content.Context);
     method public void writeToParcel(android.os.Parcel, int);
@@ -22955,9 +22965,8 @@
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
     field public static final java.lang.String META_DATA_CONTENT_RATING_SYSTEMS = "android.media.tv.metadata.CONTENT_RATING_SYSTEMS";
-    field public static final int RECORDING_ERROR_CONNECTION_FAILED = 1; // 0x1
-    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 2; // 0x2
-    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 3; // 0x3
+    field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1; // 0x1
+    field public static final int RECORDING_ERROR_RESOURCE_BUSY = 2; // 0x2
     field public static final int RECORDING_ERROR_UNKNOWN = 0; // 0x0
     field public static final long TIME_SHIFT_INVALID_TIME = -9223372036854775808L; // 0x8000000000000000L
     field public static final int TIME_SHIFT_STATUS_AVAILABLE = 3; // 0x3
@@ -22977,7 +22986,7 @@
     method public void onInputRemoved(java.lang.String);
     method public void onInputStateChanged(java.lang.String, int);
     method public void onInputUpdated(java.lang.String);
-    method public void onTvInputInfoChanged(android.media.tv.TvInputInfo);
+    method public void onTvInputInfoUpdated(android.media.tv.TvInputInfo);
   }
 
   public abstract class TvInputService extends android.app.Service {
@@ -22985,7 +22994,7 @@
     method public final android.os.IBinder onBind(android.content.Intent);
     method public android.media.tv.TvInputService.RecordingSession onCreateRecordingSession(java.lang.String);
     method public abstract android.media.tv.TvInputService.Session onCreateSession(java.lang.String);
-    method public static final void setTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
+    method public static final void updateTvInputInfo(android.content.Context, android.media.tv.TvInputInfo);
     field public static final java.lang.String SERVICE_INTERFACE = "android.media.tv.TvInputService";
     field public static final java.lang.String SERVICE_META_DATA = "android.media.tv.input";
   }
@@ -23000,14 +23009,13 @@
 
   public static abstract class TvInputService.RecordingSession {
     ctor public TvInputService.RecordingSession(android.content.Context);
-    method public void notifyConnected();
     method public void notifyError(int);
-    method public void notifyRecordingStarted();
     method public void notifyRecordingStopped(android.net.Uri);
-    method public abstract void onConnect(android.net.Uri);
-    method public abstract void onDisconnect();
-    method public abstract void onStartRecording();
+    method public void notifyTuned();
+    method public abstract void onRelease();
+    method public abstract void onStartRecording(android.net.Uri);
     method public abstract void onStopRecording();
+    method public abstract void onTune(android.net.Uri);
   }
 
   public static abstract class TvInputService.Session implements android.view.KeyEvent.Callback {
@@ -23050,19 +23058,19 @@
 
   public class TvRecordingClient {
     ctor public TvRecordingClient(android.content.Context, java.lang.String, android.media.tv.TvRecordingClient.RecordingCallback, android.os.Handler);
-    method public void connect(java.lang.String, android.net.Uri);
-    method public void disconnect();
-    method public void startRecording();
+    method public void release();
+    method public void startRecording(android.net.Uri);
     method public void stopRecording();
+    method public void tune(java.lang.String, android.net.Uri);
   }
 
   public static abstract class TvRecordingClient.RecordingCallback {
     ctor public TvRecordingClient.RecordingCallback();
-    method public void onConnected();
-    method public void onDisconnected();
+    method public void onConnectionFailed(java.lang.String);
+    method public void onDisconnected(java.lang.String);
     method public void onError(int);
-    method public void onRecordingStarted();
     method public void onRecordingStopped(android.net.Uri);
+    method public void onTuned();
   }
 
   public final class TvTrackInfo implements android.os.Parcelable {
@@ -23074,6 +23082,7 @@
     method public final java.lang.String getId();
     method public final java.lang.String getLanguage();
     method public final int getType();
+    method public final byte getVideoActiveFormatDescription();
     method public final float getVideoFrameRate();
     method public final int getVideoHeight();
     method public final float getVideoPixelAspectRatio();
@@ -23093,6 +23102,7 @@
     method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.CharSequence);
     method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
     method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
+    method public final android.media.tv.TvTrackInfo.Builder setVideoActiveFormatDescription(byte);
     method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
     method public final android.media.tv.TvTrackInfo.Builder setVideoHeight(int);
     method public final android.media.tv.TvTrackInfo.Builder setVideoPixelAspectRatio(float);
@@ -28573,7 +28583,6 @@
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
-    field public static java.lang.String DIRECTORY_HOME;
     field public static java.lang.String DIRECTORY_MOVIES;
     field public static java.lang.String DIRECTORY_MUSIC;
     field public static java.lang.String DIRECTORY_NOTIFICATIONS;
@@ -29069,6 +29078,7 @@
     method public static final int getThreadPriority(int) throws java.lang.IllegalArgumentException;
     method public static final int getUidForName(java.lang.String);
     method public static final boolean is64Bit();
+    method public static boolean isApplicationUid(int);
     method public static final void killProcess(int);
     method public static final int myPid();
     method public static final int myTid();
@@ -29250,6 +29260,7 @@
     ctor public UserHandle(android.os.Parcel);
     method public int describeContents();
     method public static int getAppId(int);
+    method public static android.os.UserHandle getUserHandleForUid(int);
     method public static android.os.UserHandle readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     method public static void writeToParcel(android.os.UserHandle, android.os.Parcel);
@@ -29363,11 +29374,27 @@
 
   public class StorageManager {
     method public java.lang.String getMountedObbPath(java.lang.String);
+    method public android.os.storage.StorageVolume getPrimaryVolume();
+    method public android.os.storage.StorageVolume[] getVolumeList();
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
   }
 
+  public class StorageVolume implements android.os.Parcelable {
+    method public android.content.Intent createAccessIntent(java.lang.String);
+    method public int describeContents();
+    method public java.lang.String getDescription(android.content.Context);
+    method public java.lang.String getState();
+    method public java.lang.String getUuid();
+    method public boolean isEmulated();
+    method public boolean isPrimary();
+    method public boolean isRemovable();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.os.storage.StorageVolume> CREATOR;
+    field public static final java.lang.String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME";
+  }
+
 }
 
 package android.preference {
@@ -31470,6 +31497,8 @@
   }
 
   protected static abstract interface ContactsContract.PhoneLookupColumns {
+    field public static final java.lang.String CONTACT_ID = "contact_id";
+    field public static final java.lang.String DATA_ID = "data_id";
     field public static final java.lang.String LABEL = "label";
     field public static final java.lang.String NORMALIZED_NUMBER = "normalized_number";
     field public static final java.lang.String NUMBER = "number";
@@ -31733,6 +31762,7 @@
     method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
+    method public java.lang.String[] getDocumentStreamTypes(java.lang.String, java.lang.String);
     method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
     method public final java.lang.String getType(android.net.Uri);
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
@@ -31753,7 +31783,7 @@
     method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
     method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
-    method public boolean removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+    method public void removeDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public java.lang.String renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
     method public final void revokeDocumentPermission(java.lang.String);
     method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
@@ -32153,6 +32183,7 @@
     field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS";
     field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS";
     field public static final java.lang.String ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
+    field public static final java.lang.String ACTION_SCREEN_READER_TUTORIAL = "android.settings.SCREEN_READER_TUTORIAL";
     field public static final java.lang.String ACTION_SEARCH_SETTINGS = "android.search.action.SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_SECURITY_SETTINGS = "android.settings.SECURITY_SETTINGS";
     field public static final java.lang.String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -34059,6 +34090,7 @@
 
   public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
     method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+    method public byte[] getAttestationChallenge();
     method public java.lang.String[] getBlockModes();
     method public java.util.Date getCertificateNotAfter();
     method public java.util.Date getCertificateNotBefore();
@@ -34083,6 +34115,7 @@
     ctor public KeyGenParameterSpec.Builder(java.lang.String, int);
     method public android.security.keystore.KeyGenParameterSpec build();
     method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+    method public android.security.keystore.KeyGenParameterSpec.Builder setAttestationChallenge(byte[]);
     method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date);
     method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date);
@@ -37797,6 +37830,7 @@
     method public java.lang.CharSequence getUserBadgedLabel(java.lang.CharSequence, android.os.UserHandle);
     method public android.content.res.XmlResourceParser getXml(java.lang.String, int, android.content.pm.ApplicationInfo);
     method public boolean hasSystemFeature(java.lang.String);
+    method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -40677,6 +40711,21 @@
     method public static android.view.FocusFinder getInstance();
   }
 
+  public final class FrameMetrics {
+    ctor public FrameMetrics(android.view.FrameMetrics);
+    method public long getMetric(int);
+    field public static final int ANIMATION_DURATION = 2; // 0x2
+    field public static final int COMMAND_ISSUE_DURATION = 6; // 0x6
+    field public static final int DRAW_DURATION = 4; // 0x4
+    field public static final int FIRST_DRAW_FRAME = 9; // 0x9
+    field public static final int INPUT_HANDLING_DURATION = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 3; // 0x3
+    field public static final int SWAP_BUFFERS_DURATION = 7; // 0x7
+    field public static final int SYNC_DURATION = 5; // 0x5
+    field public static final int TOTAL_DURATION = 8; // 0x8
+    field public static final int UNKNOWN_DELAY_DURATION = 0; // 0x0
+  }
+
   public abstract class FrameStats {
     ctor public FrameStats();
     method public final long getEndTimeNano();
@@ -43180,6 +43229,7 @@
     ctor public Window(android.content.Context);
     method public abstract void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void addFlags(int);
+    method public final void addFrameMetricsListener(android.view.Window.FrameMetricsListener, android.os.Handler);
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
@@ -43231,6 +43281,7 @@
     method public abstract boolean performContextMenuIdentifierAction(int, int);
     method public abstract boolean performPanelIdentifierAction(int, int, int);
     method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
+    method public final void removeFrameMetricsListener(android.view.Window.FrameMetricsListener);
     method public boolean requestFeature(int);
     method public abstract void restoreHierarchyState(android.os.Bundle);
     method public abstract android.os.Bundle saveHierarchyState();
@@ -43356,6 +43407,10 @@
     method public abstract android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
   }
 
+  public static abstract interface Window.FrameMetricsListener {
+    method public abstract void onMetricsAvailable(android.view.Window, android.view.FrameMetrics, int);
+  }
+
   public static abstract interface Window.OnRestrictedCaptionAreaChangedListener {
     method public abstract void onRestrictedCaptionAreaChanged(android.graphics.Rect);
   }
@@ -51466,7 +51521,6 @@
     method public static int getLength(java.lang.Object);
     method public static long getLong(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
     method public static short getShort(java.lang.Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
-    method public static java.lang.Object newArray(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int) throws java.lang.NegativeArraySizeException;
     method public static java.lang.Object newInstance(java.lang.Class<?>, int...) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException;
     method public static void set(java.lang.Object, int, java.lang.Object) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
@@ -52142,7 +52196,6 @@
 
   public class InetAddress implements java.io.Serializable {
     method public byte[] getAddress();
-    method public byte[] getAddressInternal();
     method public static java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(java.lang.String, byte[]) throws java.net.UnknownHostException;
     method public static java.net.InetAddress getByAddress(byte[]) throws java.net.UnknownHostException;
@@ -52416,7 +52469,7 @@
     method protected abstract void connect(java.net.InetAddress, int) throws java.io.IOException;
     method protected abstract void connect(java.net.SocketAddress, int) throws java.io.IOException;
     method protected abstract void create(boolean) throws java.io.IOException;
-    method public java.io.FileDescriptor getFileDescriptor();
+    method protected java.io.FileDescriptor getFileDescriptor();
     method protected java.net.InetAddress getInetAddress();
     method protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
     method protected int getLocalPort();
@@ -52958,10 +53011,6 @@
 
 package java.nio.channels {
 
-  public class AcceptPendingException extends java.lang.IllegalStateException {
-    ctor public AcceptPendingException();
-  }
-
   public class AlreadyBoundException extends java.lang.IllegalStateException {
     ctor public AlreadyBoundException();
   }
@@ -52970,68 +53019,10 @@
     ctor public AlreadyConnectedException();
   }
 
-  public abstract interface AsynchronousByteChannel implements java.nio.channels.AsynchronousChannel {
-    method public abstract void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-  }
-
-  public abstract interface AsynchronousChannel implements java.nio.channels.Channel {
-    method public abstract void close() throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousChannelGroup {
-    ctor protected AsynchronousChannelGroup(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
-    method public abstract boolean isShutdown();
-    method public abstract boolean isTerminated();
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void shutdown();
-    method public abstract void shutdownNow() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withCachedThreadPool(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withFixedThreadPool(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousChannelGroup withThreadPool(java.util.concurrent.ExecutorService) throws java.io.IOException;
-  }
-
   public class AsynchronousCloseException extends java.nio.channels.ClosedChannelException {
     ctor public AsynchronousCloseException();
   }
 
-  public abstract class AsynchronousServerSocketChannel implements java.nio.channels.AsynchronousChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousServerSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract void accept(A, java.nio.channels.CompletionHandler<java.nio.channels.AsynchronousSocketChannel, ? super A>);
-    method public abstract java.util.concurrent.Future<java.nio.channels.AsynchronousSocketChannel> accept();
-    method public final java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousServerSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-  }
-
-  public abstract class AsynchronousSocketChannel implements java.nio.channels.AsynchronousByteChannel java.nio.channels.NetworkChannel {
-    ctor protected AsynchronousSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
-    method public abstract java.nio.channels.AsynchronousSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
-    method public abstract void connect(java.net.SocketAddress, A, java.nio.channels.CompletionHandler<java.lang.Void, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Void> connect(java.net.SocketAddress);
-    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.AsynchronousSocketChannel open() throws java.io.IOException;
-    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
-    method public abstract void read(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
-    method public abstract void read(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-    method public abstract java.nio.channels.AsynchronousSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownInput() throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownOutput() throws java.io.IOException;
-    method public abstract void write(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public final void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer, ? super A>);
-    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
-    method public abstract void write(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long, ? super A>);
-  }
-
   public abstract interface ByteChannel implements java.nio.channels.ReadableByteChannel java.nio.channels.WritableByteChannel {
   }
 
@@ -53048,9 +53039,7 @@
     method public static java.nio.channels.ReadableByteChannel newChannel(java.io.InputStream);
     method public static java.nio.channels.WritableByteChannel newChannel(java.io.OutputStream);
     method public static java.io.InputStream newInputStream(java.nio.channels.ReadableByteChannel);
-    method public static java.io.InputStream newInputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.OutputStream newOutputStream(java.nio.channels.WritableByteChannel);
-    method public static java.io.OutputStream newOutputStream(java.nio.channels.AsynchronousByteChannel);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int);
     method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.lang.String);
     method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int);
@@ -53069,16 +53058,11 @@
     ctor public ClosedSelectorException();
   }
 
-  public abstract interface CompletionHandler {
-    method public abstract void completed(V, A);
-    method public abstract void failed(java.lang.Throwable, A);
-  }
-
   public class ConnectionPendingException extends java.lang.IllegalStateException {
     ctor public ConnectionPendingException();
   }
 
-  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
@@ -53157,40 +53141,14 @@
     ctor public IllegalBlockingModeException();
   }
 
-  public class IllegalChannelGroupException extends java.lang.IllegalArgumentException {
-    ctor public IllegalChannelGroupException();
-  }
-
   public class IllegalSelectorException extends java.lang.IllegalArgumentException {
     ctor public IllegalSelectorException();
   }
 
-  public class InterruptedByTimeoutException extends java.io.IOException {
-    ctor public InterruptedByTimeoutException();
-  }
-
   public abstract interface InterruptibleChannel implements java.nio.channels.Channel {
     method public abstract void close() throws java.io.IOException;
   }
 
-  public abstract class MembershipKey {
-    ctor protected MembershipKey();
-    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
-    method public abstract java.nio.channels.MulticastChannel channel();
-    method public abstract void drop();
-    method public abstract java.net.InetAddress group();
-    method public abstract boolean isValid();
-    method public abstract java.net.NetworkInterface networkInterface();
-    method public abstract java.net.InetAddress sourceAddress();
-    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
-  }
-
-  public abstract interface MulticastChannel implements java.nio.channels.NetworkChannel {
-    method public abstract void close() throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
-    method public abstract java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
-  }
-
   public abstract interface NetworkChannel implements java.nio.channels.Channel {
     method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
@@ -53240,10 +53198,6 @@
     method public final int validOps();
   }
 
-  public class ReadPendingException extends java.lang.IllegalStateException {
-    ctor public ReadPendingException();
-  }
-
   public abstract interface ReadableByteChannel implements java.nio.channels.Channel {
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
   }
@@ -53321,10 +53275,6 @@
     method public final int validOps();
   }
 
-  public class ShutdownChannelGroupException extends java.lang.IllegalStateException {
-    ctor public ShutdownChannelGroupException();
-  }
-
   public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
@@ -53360,10 +53310,6 @@
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
   }
 
-  public class WritePendingException extends java.lang.IllegalStateException {
-    ctor public WritePendingException();
-  }
-
 }
 
 package java.nio.channels.spi {
@@ -53410,15 +53356,6 @@
     method protected abstract java.nio.channels.SelectionKey register(java.nio.channels.spi.AbstractSelectableChannel, int, java.lang.Object);
   }
 
-  public abstract class AsynchronousChannelProvider {
-    ctor protected AsynchronousChannelProvider();
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public abstract java.nio.channels.AsynchronousSocketChannel openAsynchronousSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
-    method public static java.nio.channels.spi.AsynchronousChannelProvider provider();
-  }
-
   public abstract class SelectorProvider {
     ctor protected SelectorProvider();
     method public java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
@@ -54233,7 +54170,6 @@
   public abstract class Signature extends java.security.SignatureSpi {
     ctor protected Signature(java.lang.String);
     method public final java.lang.String getAlgorithm();
-    method public java.security.SignatureSpi getCurrentSpi();
     method public static java.security.Signature getInstance(java.lang.String) throws java.security.NoSuchAlgorithmException;
     method public static java.security.Signature getInstance(java.lang.String, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
     method public static java.security.Signature getInstance(java.lang.String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
@@ -56773,13 +56709,11 @@
     method public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale);
     method public java.lang.String getInternationalCurrencySymbol();
     method public char getMinusSign();
-    method public java.lang.String getMinusSignString();
     method public char getMonetaryDecimalSeparator();
     method public java.lang.String getNaN();
     method public char getPatternSeparator();
     method public char getPerMill();
     method public char getPercent();
-    method public java.lang.String getPercentString();
     method public char getZeroDigit();
     method public void setCurrency(java.util.Currency);
     method public void setCurrencySymbol(java.lang.String);
@@ -58032,8 +57966,11 @@
     method public static boolean equals(java.lang.Object, java.lang.Object);
     method public static int hash(java.lang.Object...);
     method public static int hashCode(java.lang.Object);
+    method public static boolean isNull(java.lang.Object);
+    method public static boolean nonNull(java.lang.Object);
     method public static T requireNonNull(T);
     method public static T requireNonNull(T, java.lang.String);
+    method public static T requireNonNull(T, java.util.function.Supplier<java.lang.String>);
     method public static java.lang.String toString(java.lang.Object);
     method public static java.lang.String toString(java.lang.Object, java.lang.String);
   }
@@ -59738,6 +59675,217 @@
 
 }
 
+package java.util.function {
+
+  public abstract interface BiConsumer {
+    method public abstract void accept(T, U);
+    method public default java.util.function.BiConsumer<T, U> andThen(java.util.function.BiConsumer<? super T, ? super U>);
+  }
+
+  public abstract interface BiFunction {
+    method public default java.util.function.BiFunction<T, U, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T, U);
+  }
+
+  public abstract interface BiPredicate {
+    method public default java.util.function.BiPredicate<T, U> and(java.util.function.BiPredicate<? super T, ? super U>);
+    method public default java.util.function.BiPredicate<T, U> negate();
+    method public default java.util.function.BiPredicate<T, U> or(java.util.function.BiPredicate<? super T, ? super U>);
+    method public abstract boolean test(T, U);
+  }
+
+  public abstract interface BinaryOperator implements java.util.function.BiFunction {
+    method public static java.util.function.BinaryOperator<T> maxBy(java.util.Comparator<? super T>);
+    method public static java.util.function.BinaryOperator<T> minBy(java.util.Comparator<? super T>);
+  }
+
+  public abstract interface BooleanSupplier {
+    method public abstract boolean getAsBoolean();
+  }
+
+  public abstract interface Consumer {
+    method public abstract void accept(T);
+    method public default java.util.function.Consumer<T> andThen(java.util.function.Consumer<? super T>);
+  }
+
+  public abstract interface DoubleBinaryOperator {
+    method public abstract double applyAsDouble(double, double);
+  }
+
+  public abstract interface DoubleConsumer {
+    method public abstract void accept(double);
+    method public default java.util.function.DoubleConsumer andThen(java.util.function.DoubleConsumer);
+  }
+
+  public abstract interface DoubleFunction {
+    method public abstract R apply(double);
+  }
+
+  public abstract interface DoublePredicate {
+    method public default java.util.function.DoublePredicate and(java.util.function.DoublePredicate);
+    method public default java.util.function.DoublePredicate negate();
+    method public default java.util.function.DoublePredicate or(java.util.function.DoublePredicate);
+    method public abstract boolean test(double);
+  }
+
+  public abstract interface DoubleSupplier {
+    method public abstract double getAsDouble();
+  }
+
+  public abstract interface DoubleToIntFunction {
+    method public abstract int applyAsInt(double);
+  }
+
+  public abstract interface DoubleToLongFunction {
+    method public abstract long applyAsLong(double);
+  }
+
+  public abstract interface DoubleUnaryOperator {
+    method public default java.util.function.DoubleUnaryOperator andThen(java.util.function.DoubleUnaryOperator);
+    method public abstract double applyAsDouble(double);
+    method public default java.util.function.DoubleUnaryOperator compose(java.util.function.DoubleUnaryOperator);
+    method public static java.util.function.DoubleUnaryOperator identity();
+  }
+
+  public abstract interface Function {
+    method public default java.util.function.Function<T, V> andThen(java.util.function.Function<? super R, ? extends V>);
+    method public abstract R apply(T);
+    method public default java.util.function.Function<V, R> compose(java.util.function.Function<? super V, ? extends T>);
+    method public static java.util.function.Function<T, T> identity();
+  }
+
+  public abstract interface IntBinaryOperator {
+    method public abstract int applyAsInt(int, int);
+  }
+
+  public abstract interface IntConsumer {
+    method public abstract void accept(int);
+    method public default java.util.function.IntConsumer andThen(java.util.function.IntConsumer);
+  }
+
+  public abstract interface IntFunction {
+    method public abstract R apply(int);
+  }
+
+  public abstract interface IntPredicate {
+    method public default java.util.function.IntPredicate and(java.util.function.IntPredicate);
+    method public default java.util.function.IntPredicate negate();
+    method public default java.util.function.IntPredicate or(java.util.function.IntPredicate);
+    method public abstract boolean test(int);
+  }
+
+  public abstract interface IntSupplier {
+    method public abstract int getAsInt();
+  }
+
+  public abstract interface IntToDoubleFunction {
+    method public abstract double applyAsDouble(int);
+  }
+
+  public abstract interface IntToLongFunction {
+    method public abstract long applyAsLong(int);
+  }
+
+  public abstract interface IntUnaryOperator {
+    method public default java.util.function.IntUnaryOperator andThen(java.util.function.IntUnaryOperator);
+    method public abstract int applyAsInt(int);
+    method public default java.util.function.IntUnaryOperator compose(java.util.function.IntUnaryOperator);
+    method public static java.util.function.IntUnaryOperator identity();
+  }
+
+  public abstract interface LongBinaryOperator {
+    method public abstract long applyAsLong(long, long);
+  }
+
+  public abstract interface LongConsumer {
+    method public abstract void accept(long);
+    method public default java.util.function.LongConsumer andThen(java.util.function.LongConsumer);
+  }
+
+  public abstract interface LongFunction {
+    method public abstract R apply(long);
+  }
+
+  public abstract interface LongPredicate {
+    method public default java.util.function.LongPredicate and(java.util.function.LongPredicate);
+    method public default java.util.function.LongPredicate negate();
+    method public default java.util.function.LongPredicate or(java.util.function.LongPredicate);
+    method public abstract boolean test(long);
+  }
+
+  public abstract interface LongSupplier {
+    method public abstract long getAsLong();
+  }
+
+  public abstract interface LongToDoubleFunction {
+    method public abstract double applyAsDouble(long);
+  }
+
+  public abstract interface LongToIntFunction {
+    method public abstract int applyAsInt(long);
+  }
+
+  public abstract interface LongUnaryOperator {
+    method public default java.util.function.LongUnaryOperator andThen(java.util.function.LongUnaryOperator);
+    method public abstract long applyAsLong(long);
+    method public default java.util.function.LongUnaryOperator compose(java.util.function.LongUnaryOperator);
+    method public static java.util.function.LongUnaryOperator identity();
+  }
+
+  public abstract interface ObjDoubleConsumer {
+    method public abstract void accept(T, double);
+  }
+
+  public abstract interface ObjIntConsumer {
+    method public abstract void accept(T, int);
+  }
+
+  public abstract interface ObjLongConsumer {
+    method public abstract void accept(T, long);
+  }
+
+  public abstract interface Predicate {
+    method public default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T>);
+    method public static java.util.function.Predicate<T> isEqual(java.lang.Object);
+    method public default java.util.function.Predicate<T> negate();
+    method public default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T>);
+    method public abstract boolean test(T);
+  }
+
+  public abstract interface Supplier {
+    method public abstract T get();
+  }
+
+  public abstract interface ToDoubleBiFunction {
+    method public abstract double applyAsDouble(T, U);
+  }
+
+  public abstract interface ToDoubleFunction {
+    method public abstract double applyAsDouble(T);
+  }
+
+  public abstract interface ToIntBiFunction {
+    method public abstract int applyAsInt(T, U);
+  }
+
+  public abstract interface ToIntFunction {
+    method public abstract int applyAsInt(T);
+  }
+
+  public abstract interface ToLongBiFunction {
+    method public abstract long applyAsLong(T, U);
+  }
+
+  public abstract interface ToLongFunction {
+    method public abstract long applyAsLong(T);
+  }
+
+  public abstract interface UnaryOperator implements java.util.function.Function {
+    method public static java.util.function.UnaryOperator<T> identity();
+  }
+
+}
+
 package java.util.jar {
 
   public class Attributes implements java.lang.Cloneable java.util.Map {
@@ -62472,14 +62620,6 @@
     method public abstract boolean isDestroyed();
   }
 
-  public abstract deprecated class Policy {
-    ctor protected Policy();
-    method public abstract java.security.PermissionCollection getPermissions(javax.security.auth.Subject, java.security.CodeSource);
-    method public static javax.security.auth.Policy getPolicy();
-    method public abstract void refresh();
-    method public static void setPolicy(javax.security.auth.Policy);
-  }
-
   public final class PrivateCredentialPermission extends java.security.Permission {
     ctor public PrivateCredentialPermission(java.lang.String, java.lang.String);
     method public boolean equals(java.lang.Object);
@@ -62544,43 +62684,6 @@
 
 package javax.security.auth.login {
 
-  public class AppConfigurationEntry {
-    ctor public AppConfigurationEntry(java.lang.String, javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag, java.util.Map<java.lang.String, ?>);
-    method public javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag getControlFlag();
-    method public java.lang.String getLoginModuleName();
-    method public java.util.Map<java.lang.String, ?> getOptions();
-  }
-
-  public static class AppConfigurationEntry.LoginModuleControlFlag {
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag OPTIONAL;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUIRED;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag REQUISITE;
-    field public static final javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag SUFFICIENT;
-  }
-
-  public abstract class Configuration {
-    ctor protected Configuration();
-    method public abstract javax.security.auth.login.AppConfigurationEntry[] getAppConfigurationEntry(java.lang.String);
-    method public static javax.security.auth.login.Configuration getConfiguration();
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters) throws java.security.NoSuchAlgorithmException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.lang.String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
-    method public static javax.security.auth.login.Configuration getInstance(java.lang.String, javax.security.auth.login.Configuration.Parameters, java.security.Provider) throws java.security.NoSuchAlgorithmException;
-    method public javax.security.auth.login.Configuration.Parameters getParameters();
-    method public java.security.Provider getProvider();
-    method public java.lang.String getType();
-    method public void refresh();
-    method public static void setConfiguration(javax.security.auth.login.Configuration);
-  }
-
-  public static abstract interface Configuration.Parameters {
-  }
-
-  public abstract class ConfigurationSpi {
-    ctor public ConfigurationSpi();
-    method protected abstract javax.security.auth.login.AppConfigurationEntry[] engineGetAppConfigurationEntry(java.lang.String);
-    method protected void engineRefresh();
-  }
-
   public class LoginException extends java.security.GeneralSecurityException {
     ctor public LoginException();
     ctor public LoginException(java.lang.String);
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index acc68cf..eedb82b 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -167,6 +167,7 @@
                 "       am stack positiontask <TASK_ID> <STACK_ID> <POSITION>\n" +
                 "       am stack list\n" +
                 "       am stack info <STACK_ID>\n" +
+                "       am stack remove <STACK_ID>\n" +
                 "       am task lock <TASK_ID>\n" +
                 "       am task lock stop\n" +
                 "       am task resizeable <TASK_ID> [0 (unresizeable) | 1 (crop_windows) | 2 (resizeable) | 3 (resizeable_and_pipable)]\n" +
@@ -324,6 +325,8 @@
                 "\n" +
                 "am stack info: display the information about activity stack <STACK_ID>.\n" +
                 "\n" +
+                "am stack remove: remove stack <STACK_ID>.\n" +
+                "\n" +
                 "am task lock: bring <TASK_ID> to the front and don't allow other tasks to run.\n" +
                 "\n" +
                 "am task lock stop: end the current task lock.\n" +
@@ -1126,14 +1129,19 @@
         }
     }
 
+    private byte[] argToBytes(String arg) {
+        if (arg.equals("!")) {
+            return null;
+        } else {
+            return HexDump.hexStringToByteArray(arg);
+        }
+    }
+
     private void runUnlockUser() throws Exception {
         int userId = Integer.parseInt(nextArgRequired());
-        String tokenHex = nextArg();
-        byte[] token = null;
-        if (tokenHex != null) {
-            token = HexDump.hexStringToByteArray(tokenHex);
-        }
-        boolean success = mAm.unlockUser(userId, token);
+        byte[] token = argToBytes(nextArgRequired());
+        byte[] secret = argToBytes(nextArgRequired());
+        boolean success = mAm.unlockUser(userId, token, secret);
         if (success) {
             System.out.println("Success: user unlocked");
         } else {
@@ -1727,6 +1735,9 @@
             case "size-docked-stack-test":
                 runStackSizeDockedStackTest();
                 break;
+            case "remove":
+                runStackRemove();
+                break;
             default:
                 showError("Error: unknown command '" + op + "'");
                 break;
@@ -1863,6 +1874,12 @@
         }
     }
 
+    private void runStackRemove() throws Exception {
+        String stackIdStr = nextArgRequired();
+        int stackId = Integer.valueOf(stackIdStr);
+        mAm.removeStack(stackId);
+    }
+
     private void runMoveTopActivityToPinnedStack() throws Exception {
         int stackId = Integer.valueOf(nextArgRequired());
         final Rect bounds = getBounds();
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 67d63a4..69b5a17 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -23,11 +23,15 @@
 import android.app.backup.IBackupObserver;
 import android.app.backup.IRestoreObserver;
 import android.app.backup.IRestoreSession;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 
 import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 
 public final class Bmgr {
     IBackupManager mBmgr;
@@ -36,7 +40,9 @@
     static final String BMGR_NOT_RUNNING_ERR =
             "Error: Could not access the Backup Manager.  Is the system running?";
     static final String TRANSPORT_NOT_RUNNING_ERR =
-        "Error: Could not access the backup transport.  Is the system running?";
+            "Error: Could not access the backup transport.  Is the system running?";
+    static final String PM_NOT_RUNNING_ERR =
+            "Error: Could not access the Package Manager.  Is the system running?";
 
     private String[] mArgs;
     private int mNextArg;
@@ -203,19 +209,20 @@
         @Override
         public void onUpdate(String currentPackage, BackupProgress backupProgress) {
             System.out.println(
-                "onUpdate: " + currentPackage + " with progress: " + backupProgress.bytesTransferred
+                "Package " + currentPackage + " with progress: " + backupProgress.bytesTransferred
                     + "/" + backupProgress.bytesExpected);
         }
 
         @Override
         public void onResult(String currentPackage, int status) {
-            System.out.println("onResult: " + currentPackage + " with result: "
+            System.out.println("Package " + currentPackage + " with result: "
                     + convertBackupStatusToString(status));
         }
 
         @Override
         public void backupFinished(int status) {
-            System.out.println("backupFinished: " + convertBackupStatusToString(status));
+            System.out.println("Backup finished with result: "
+                    + convertBackupStatusToString(status));
             synchronized (this) {
                 done = true;
                 this.notify();
@@ -251,32 +258,84 @@
                 return "Transport rejected package";
             case BackupManager.ERROR_AGENT_FAILURE:
                 return "Agent error";
+            case BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED:
+                return "Size quota exceeded";
             default:
                 return "Unknown error";
         }
     }
 
+    private void backupNowAllPackages() {
+        int userId = UserHandle.USER_SYSTEM;
+        IPackageManager mPm =
+                IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        if (mPm == null) {
+            System.err.println(PM_NOT_RUNNING_ERR);
+            return;
+        }
+        List<PackageInfo> installedPackages = null;
+        try {
+            installedPackages =  mPm.getInstalledPackages(0, userId).getList();
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(PM_NOT_RUNNING_ERR);
+        }
+        if (installedPackages != null) {
+            List<String> packages = new ArrayList<>();
+            for (PackageInfo pi : installedPackages) {
+                try {
+                    if (mBmgr.isAppEligibleForBackup(pi.packageName)) {
+                        packages.add(pi.packageName);
+                    }
+                } catch (RemoteException e) {
+                    System.err.println(e.toString());
+                    System.err.println(BMGR_NOT_RUNNING_ERR);
+                }
+            }
+            backupNowPackages(packages);
+        }
+    }
+
+    private void backupNowPackages(List<String> packages) {
+        try {
+            BackupObserver observer = new BackupObserver();
+            int err = mBmgr.requestBackup(packages.toArray(new String[packages.size()]), observer);
+            if (err == 0) {
+                // Off and running -- wait for the backup to complete
+                observer.waitForCompletion();
+            } else {
+                System.err.println("Unable to run backup");
+            }
+        } catch (RemoteException e) {
+            System.err.println(e.toString());
+            System.err.println(BMGR_NOT_RUNNING_ERR);
+        }
+    }
+
     private void doBackupNow() {
         String pkg;
+        boolean backupAll = false;
         ArrayList<String> allPkgs = new ArrayList<String>();
         while ((pkg = nextArg()) != null) {
-            allPkgs.add(pkg);
-        }
-        if (allPkgs.size() > 0) {
-            try {
-                BackupObserver observer = new BackupObserver();
-                int err = mBmgr.requestBackup(allPkgs.toArray(new String[allPkgs.size()]), observer);
-                if (err == 0) {
-                    // Off and running -- wait for the backup to complete
-                    observer.waitForCompletion();
-                } else {
-                    System.err.println("Unable to run backup");
-                }
-            } catch (RemoteException e) {
-                System.err.println(e.toString());
-                System.err.println(BMGR_NOT_RUNNING_ERR);
+            if (pkg.equals("--all")) {
+                backupAll = true;
+            } else {
+                allPkgs.add(pkg);
             }
         }
+        if (backupAll) {
+            if (allPkgs.size() == 0) {
+                System.out.println("Running backup for all packages.");
+                backupNowAllPackages();
+            } else {
+                System.err.println("Provide only '--all' flag or list of packages.");
+            }
+        } else if (allPkgs.size() > 0) {
+            System.out.println("Running backup for " + allPkgs.size() +" requested packages.");
+            backupNowPackages(allPkgs);
+        } else {
+            System.err.println("Provide '--all' flag or list of packages.");
+        }
     }
 
     private void doTransport() {
@@ -568,6 +627,7 @@
         System.err.println("       bmgr run");
         System.err.println("       bmgr wipe TRANSPORT PACKAGE");
         System.err.println("       bmgr fullbackup PACKAGE...");
+        System.err.println("       bmgr backupnow --all|PACKAGE...");
         System.err.println("");
         System.err.println("The 'backup' command schedules a backup pass for the named package.");
         System.err.println("Note that the backup pass will effectively be a no-op if the package");
@@ -620,6 +680,7 @@
         System.err.println("packages.  The data is sent via the currently active transport.");
         System.err.println("");
         System.err.println("The 'backupnow' command runs an immediate backup for one or more packages.");
+        System.err.println("    --all flag runs backup for all eligible packages.");
         System.err.println("For each package it will run key/value or full data backup ");
         System.err.println("depending on the package's manifest declarations.");
         System.err.println("The data is sent via the currently active transport.");
diff --git a/cmds/svc/src/com/android/commands/svc/NfcCommand.java b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
index e0f09ee..8e9791f 100644
--- a/cmds/svc/src/com/android/commands/svc/NfcCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/NfcCommand.java
@@ -58,7 +58,7 @@
                 IPackageManager pm = IPackageManager.Stub.asInterface(
                         ServiceManager.getService("package"));
                 try {
-                    if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
+                    if (pm.hasSystemFeature(PackageManager.FEATURE_NFC, 0)) {
                         INfcAdapter nfc = INfcAdapter.Stub
                                 .asInterface(ServiceManager.getService(Context.NFC_SERVICE));
                         try {
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index c96cca2..4bc6b97 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -624,8 +624,7 @@
                 gesture, 100);
         try {
             synchronized (mLock) {
-                connection.sendMotionEvents(++mGestureStatusCallbackSequence,
-                        new ParceledListSlice<>(events));
+                mGestureStatusCallbackSequence++;
                 if (callback != null) {
                     if (mGestureStatusCallbackInfos == null) {
                         mGestureStatusCallbackInfos = new SparseArray<>();
@@ -634,6 +633,8 @@
                             callback, handler);
                     mGestureStatusCallbackInfos.put(mGestureStatusCallbackSequence, callbackInfo);
                 }
+                connection.sendMotionEvents(mGestureStatusCallbackSequence,
+                        new ParceledListSlice<>(events));
             }
         } catch (RemoteException re) {
             throw new RuntimeException(re);
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 980329f..3385a17 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -807,6 +807,8 @@
     }
 
     /**
+     * AnimatorSet is only reversible when the set contains no sequential animation, and no child
+     * animators have a start delay.
      * @hide
      */
     @Override
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 622012e..e3adbda 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import static java.lang.Character.MIN_VALUE;
+
 import android.annotation.CallSuper;
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
@@ -26,20 +28,6 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.StyleRes;
-import android.os.PersistableBundle;
-import android.transition.Scene;
-import android.transition.TransitionManager;
-import android.util.ArrayMap;
-import android.util.SuperNotCalledException;
-import android.view.DragEvent;
-import android.view.DropPermissions;
-import android.view.Window.WindowControllerCallback;
-import android.widget.Toolbar;
-
-import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.app.ToolbarActionBar;
-
 import android.annotation.SystemApi;
 import android.app.admin.DevicePolicyManager;
 import android.app.assist.AssistContent;
@@ -61,7 +49,13 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.ShapeDrawable;
 import android.media.AudioManager;
 import android.media.session.MediaController;
 import android.net.Uri;
@@ -71,6 +65,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.StrictMode;
 import android.os.UserHandle;
@@ -78,16 +73,22 @@
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.method.TextKeyListener;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SuperNotCalledException;
 import android.view.ActionMode;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.ContextThemeWrapper;
+import android.view.DragEvent;
+import android.view.DropPermissions;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
@@ -104,11 +105,17 @@
 import android.view.ViewManager;
 import android.view.ViewRootImpl;
 import android.view.Window;
+import android.view.Window.WindowControllerCallback;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.AdapterView;
+import android.widget.Toolbar;
 
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.app.ToolbarActionBar;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.DecorView;
 import com.android.internal.policy.PhoneWindow;
 
 import java.io.FileDescriptor;
@@ -119,8 +126,6 @@
 import java.util.HashMap;
 import java.util.List;
 
-import static java.lang.Character.MIN_VALUE;
-
 /**
  * An activity is a single, focused thing that the user can do.  Almost all
  * activities interact with the user, so the Activity class takes care of
@@ -3974,17 +3979,56 @@
         // Get the primary color and update the TaskDescription for this activity
         if (theme != null) {
             TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
+            int windowBgResourceId = a.getResourceId(
+                    com.android.internal.R.styleable.Window_windowBackground, 0);
+            int windowBgFallbackResourceId = a.getResourceId(
+                    com.android.internal.R.styleable.Window_windowBackgroundFallback, 0);
             int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0);
+            int colorBg = tryExtractColorFromDrawable(DecorView.getResizingBackgroundDrawable(this,
+                    windowBgResourceId, windowBgFallbackResourceId));
             a.recycle();
             if (colorPrimary != 0) {
-                ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null,
-                        colorPrimary);
-                setTaskDescription(v);
+                ActivityManager.TaskDescription td = new ActivityManager.TaskDescription();
+                if (Color.alpha(colorPrimary) == 0xFF) {
+                    td.setPrimaryColor(colorPrimary);
+                }
+                if (Color.alpha(colorBg) == 0xFF) {
+                    td.setBackgroundColor(colorBg);
+                }
+                setTaskDescription(td);
             }
         }
     }
 
     /**
+     * Attempts to extract the color from a given drawable.
+     *
+     * @return the extracted color or 0 if no color could be extracted.
+     */
+    private int tryExtractColorFromDrawable(Drawable drawable) {
+        if (drawable instanceof ColorDrawable) {
+            return ((ColorDrawable) drawable).getColor();
+        } else if (drawable instanceof InsetDrawable) {
+            return tryExtractColorFromDrawable(((InsetDrawable) drawable).getDrawable());
+        } else if (drawable instanceof ShapeDrawable) {
+            Paint p = ((ShapeDrawable) drawable).getPaint();
+            if (p != null) {
+                return p.getColor();
+            }
+        } else if (drawable instanceof LayerDrawable) {
+            LayerDrawable ld = (LayerDrawable) drawable;
+            int numLayers = ld.getNumberOfLayers();
+            for (int i = 0; i < numLayers; i++) {
+                int color = tryExtractColorFromDrawable(ld.getDrawable(i));
+                if (color != 0) {
+                    return color;
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
      * Requests permissions to be granted to this application. These permissions
      * must be requested in your manifest, they should not be granted to your app,
      * and they should have protection level {@link android.content.pm.PermissionInfo
@@ -5612,8 +5656,8 @@
         if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
             final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
             final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
-            td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
-                    taskDescription.getPrimaryColor());
+            td = new ActivityManager.TaskDescription(taskDescription);
+            td.setIcon(icon);
         } else {
             td = taskDescription;
         }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 1eb2fe2..7771139 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -581,8 +581,12 @@
          * the task to the specified stack.
          */
         public static boolean useAnimationSpecForAppTransition(int stackId) {
+
+            // TODO: INVALID_STACK_ID is also animated because we don't persist stack id's across
+            // reboots.
             return stackId == FREEFORM_WORKSPACE_STACK_ID
-                    || stackId == FULLSCREEN_WORKSPACE_STACK_ID || stackId == DOCKED_STACK_ID;
+                    || stackId == FULLSCREEN_WORKSPACE_STACK_ID || stackId == DOCKED_STACK_ID
+                    || stackId == INVALID_STACK_ID;
         }
 
         /** Returns true if the windows in the stack can receive input keys. */
@@ -632,6 +636,17 @@
         public static boolean useWindowFrameForBackdrop(int stackId) {
             return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID;
         }
+
+        /**
+         * Returns true if a window from the specified stack with {@param stackId} are normally
+         * fullscreen, i. e. they can become the top opaque fullscreen window, meaning that it
+         * controls system bars, lockscreen occluded/dismissing state, screen rotation animation,
+         * etc.
+         */
+        public static boolean normallyFullscreenWindows(int stackId) {
+            return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID
+                    && stackId != DOCKED_STACK_ID;
+        }
     }
 
     /**
@@ -863,8 +878,10 @@
         public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
         private static final String ATTR_TASKDESCRIPTIONLABEL =
                 ATTR_TASKDESCRIPTION_PREFIX + "label";
-        private static final String ATTR_TASKDESCRIPTIONCOLOR =
+        private static final String ATTR_TASKDESCRIPTIONCOLOR_PRIMARY =
                 ATTR_TASKDESCRIPTION_PREFIX + "color";
+        private static final String ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND =
+                ATTR_TASKDESCRIPTION_PREFIX + "colorBackground";
         private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
                 ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";
 
@@ -872,28 +889,21 @@
         private Bitmap mIcon;
         private String mIconFilename;
         private int mColorPrimary;
+        private int mColorBackground;
 
         /**
          * Creates the TaskDescription to the specified values.
          *
          * @param label A label and description of the current state of this task.
          * @param icon An icon that represents the current state of this task.
-         * @param colorPrimary A color to override the theme's primary color.  This color must be opaque.
+         * @param colorPrimary A color to override the theme's primary color.  This color must be
+         *                     opaque.
          */
         public TaskDescription(String label, Bitmap icon, int colorPrimary) {
+            this(label, icon, null, colorPrimary, 0);
             if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) {
                 throw new RuntimeException("A TaskDescription's primary color should be opaque");
             }
-
-            mLabel = label;
-            mIcon = icon;
-            mColorPrimary = colorPrimary;
-        }
-
-        /** @hide */
-        public TaskDescription(String label, int colorPrimary, String iconFilename) {
-            this(label, null, colorPrimary);
-            mIconFilename = iconFilename;
         }
 
         /**
@@ -903,7 +913,7 @@
          * @param icon An icon that represents the current state of this activity.
          */
         public TaskDescription(String label, Bitmap icon) {
-            this(label, icon, 0);
+            this(label, icon, null, 0, 0);
         }
 
         /**
@@ -912,14 +922,24 @@
          * @param label A label and description of the current state of this activity.
          */
         public TaskDescription(String label) {
-            this(label, null, 0);
+            this(label, null, null, 0, 0);
         }
 
         /**
          * Creates an empty TaskDescription.
          */
         public TaskDescription() {
-            this(null, null, 0);
+            this(null, null, null, 0, 0);
+        }
+
+        /** @hide */
+        public TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary,
+                int colorBackground) {
+            mLabel = label;
+            mIcon = icon;
+            mIconFilename = iconFilename;
+            mColorPrimary = colorPrimary;
+            mColorBackground = colorBackground;
         }
 
         /**
@@ -928,8 +948,9 @@
         public TaskDescription(TaskDescription td) {
             mLabel = td.mLabel;
             mIcon = td.mIcon;
-            mColorPrimary = td.mColorPrimary;
             mIconFilename = td.mIconFilename;
+            mColorPrimary = td.mColorPrimary;
+            mColorBackground = td.mColorBackground;
         }
 
         private TaskDescription(Parcel source) {
@@ -957,6 +978,18 @@
         }
 
         /**
+         * Sets the background color for this task description.
+         * @hide
+         */
+        public void setBackgroundColor(int backgroundColor) {
+            // Ensure that the given color is valid
+            if ((backgroundColor != 0) && (Color.alpha(backgroundColor) != 255)) {
+                throw new RuntimeException("A TaskDescription's background color should be opaque");
+            }
+            mColorBackground = backgroundColor;
+        }
+
+        /**
          * Sets the icon for this task description.
          * @hide
          */
@@ -1005,8 +1038,8 @@
         public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) {
             if (iconFilename != null) {
                 try {
-                    return ActivityManagerNative.getDefault().
-                            getTaskDescriptionIcon(iconFilename, userId);
+                    return ActivityManagerNative.getDefault().getTaskDescriptionIcon(iconFilename,
+                            userId);
                 } catch (RemoteException e) {
                 }
             }
@@ -1020,13 +1053,26 @@
             return mColorPrimary;
         }
 
+        /**
+         * @return The background color.
+         * @hide
+         */
+        public int getBackgroundColor() {
+            return mColorBackground;
+        }
+
         /** @hide */
         public void saveToXml(XmlSerializer out) throws IOException {
             if (mLabel != null) {
                 out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
             }
             if (mColorPrimary != 0) {
-                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary));
+                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY,
+                        Integer.toHexString(mColorPrimary));
+            }
+            if (mColorBackground != 0) {
+                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND,
+                        Integer.toHexString(mColorBackground));
             }
             if (mIconFilename != null) {
                 out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
@@ -1037,8 +1083,10 @@
         public void restoreFromXml(String attrName, String attrValue) {
             if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
                 setLabel(attrValue);
-            } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
+            } else if (ATTR_TASKDESCRIPTIONCOLOR_PRIMARY.equals(attrName)) {
                 setPrimaryColor((int) Long.parseLong(attrValue, 16));
+            } else if (ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND.equals(attrName)) {
+                setBackgroundColor((int) Long.parseLong(attrValue, 16));
             } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
                 setIconFilename(attrValue);
             }
@@ -1064,6 +1112,7 @@
                 mIcon.writeToParcel(dest, 0);
             }
             dest.writeInt(mColorPrimary);
+            dest.writeInt(mColorBackground);
             if (mIconFilename == null) {
                 dest.writeInt(0);
             } else {
@@ -1076,6 +1125,7 @@
             mLabel = source.readInt() > 0 ? source.readString() : null;
             mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
             mColorPrimary = source.readInt();
+            mColorBackground = source.readInt();
             mIconFilename = source.readInt() > 0 ? source.readString() : null;
         }
 
@@ -1092,7 +1142,8 @@
         @Override
         public String toString() {
             return "TaskDescription Label: " + mLabel + " Icon: " + mIcon +
-                    " colorPrimary: " + mColorPrimary;
+                    " IconFilename: " + mIconFilename + " colorPrimary: " + mColorPrimary +
+                    " colorBackground: " + mColorBackground;
         }
     }
 
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a3160f4..04979ef 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2080,7 +2080,8 @@
             data.enforceInterface(IActivityManager.descriptor);
             int userId = data.readInt();
             byte[] token = data.createByteArray();
-            boolean result = unlockUser(userId, token);
+            byte[] secret = data.createByteArray();
+            boolean result = unlockUser(userId, token, secret);
             reply.writeNoException();
             reply.writeInt(result ? 1 : 0);
             return true;
@@ -2881,6 +2882,18 @@
             reply.writeInt(isForeground ? 1 : 0);
             return true;
         }
+        case NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            reply.writeNoException();
+            return true;
+        }
+        case REMOVE_STACK: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int stackId = data.readInt();
+            removeStack(stackId);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -5571,12 +5584,13 @@
         return result;
     }
 
-    public boolean unlockUser(int userId, byte[] token) throws RemoteException {
+    public boolean unlockUser(int userId, byte[] token, byte[] secret) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
         data.writeInt(userId);
         data.writeByteArray(token);
+        data.writeByteArray(secret);
         mRemote.transact(IActivityManager.UNLOCK_USER_TRANSACTION, data, reply, 0);
         reply.readException();
         boolean result = reply.readInt() != 0;
@@ -6730,5 +6744,27 @@
         return isForeground;
     };
 
+    @Override
+    public void notifyPinnedStackAnimationEnded() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION, data, reply, 0);
+        data.recycle();
+        reply.recycle();
+    };
+
+    @Override
+    public void removeStack(int stackId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(stackId);
+        mRemote.transact(REMOVE_STACK, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index af840d0..198bfb0a 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -933,6 +933,17 @@
         return -1;
     }
 
+    protected void setTransitioningViewsVisiblity(int visiblity, boolean invalidate) {
+        final int numElements = mTransitioningViews == null ? 0 : mTransitioningViews.size();
+        for (int i = 0; i < numElements; i++) {
+            final View view = mTransitioningViews.get(i);
+            view.setTransitionVisibility(visiblity);
+            if (invalidate) {
+                view.invalidate();
+            }
+        }
+    }
+
     private static class FixedEpicenterCallback extends Transition.EpicenterCallback {
         private Rect mEpicenter;
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index c071162..91eabcc 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.XmlRes;
+import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Intent;
@@ -429,6 +430,16 @@
         }
     }
 
+    /** @hide */
+    @Override
+    public @Nullable String getServicesSystemSharedLibraryPackageName() {
+        try {
+            return mPM.getServicesSystemSharedLibraryPackageName();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+    }
+
     @Override
     public FeatureInfo[] getSystemAvailableFeatures() {
         try {
@@ -440,8 +451,13 @@
 
     @Override
     public boolean hasSystemFeature(String name) {
+        return hasSystemFeature(name, 0);
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
         try {
-            return mPM.hasSystemFeature(name);
+            return mPM.hasSystemFeature(name, version);
         } catch (RemoteException e) {
             throw new RuntimeException("Package manager has died", e);
         }
@@ -1744,7 +1760,7 @@
         return candidates;
     }
 
-    private static boolean isPackageCandidateVolume(
+    private boolean isPackageCandidateVolume(
             ContextImpl context, ApplicationInfo app, VolumeInfo vol) {
         final boolean forceAllowOnExternal = Settings.Global.getInt(
                 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
@@ -1774,6 +1790,15 @@
             return app.isInternal();
         }
 
+        // Some apps can't be moved. (e.g. device admins)
+        try {
+            if (mPM.isPackageDeviceAdminOnAnyUser(app.packageName)) {
+                return false;
+            }
+        } catch (RemoteException e) {
+            throw new RuntimeException("Package manager has died", e);
+        }
+
         // Otherwise we can move to any private volume
         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
     }
@@ -1892,9 +1917,20 @@
     }
 
     @Override
-    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
         try {
-            return mPM.setPackageSuspendedAsUser(packageName, suspended, userId);
+            return mPM.setPackagesSuspendedAsUser(packageNames, suspended, userId);
+        } catch (RemoteException e) {
+            // Should never happen!
+        }
+        return packageNames;
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        try {
+            return mPM.isPackageSuspendedForUser(packageName, userId);
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index eec503b..5e8d190 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -134,7 +134,14 @@
     /**
      * Map from package name, to preference name, to cached preferences.
      */
-    private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefs;
+    @GuardedBy("ContextImpl.class")
+    private static ArrayMap<String, ArrayMap<File, SharedPreferencesImpl>> sSharedPrefsCache;
+
+    /**
+     * Map from preference name to generated path.
+     */
+    @GuardedBy("ContextImpl.class")
+    private ArrayMap<String, File> mSharedPrefsPaths;
 
     final ActivityThread mMainThread;
     final LoadedApk mPackageInfo;
@@ -335,7 +342,17 @@
             }
         }
 
-        final File file = getSharedPreferencesPath(name);
+        File file;
+        synchronized (ContextImpl.class) {
+            if (mSharedPrefsPaths == null) {
+                mSharedPrefsPaths = new ArrayMap<>();
+            }
+            file = mSharedPrefsPaths.get(name);
+            if (file == null) {
+                file = getSharedPreferencesPath(name);
+                mSharedPrefsPaths.put(name, file);
+            }
+        }
         return getSharedPreferences(file, mode);
     }
 
@@ -363,15 +380,15 @@
     }
 
     private ArrayMap<File, SharedPreferencesImpl> getSharedPreferencesCacheLocked() {
-        if (sSharedPrefs == null) {
-            sSharedPrefs = new ArrayMap<>();
+        if (sSharedPrefsCache == null) {
+            sSharedPrefsCache = new ArrayMap<>();
         }
 
         final String packageName = getPackageName();
-        ArrayMap<File, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
+        ArrayMap<File, SharedPreferencesImpl> packagePrefs = sSharedPrefsCache.get(packageName);
         if (packagePrefs == null) {
             packagePrefs = new ArrayMap<>();
-            sSharedPrefs.put(packageName, packagePrefs);
+            sSharedPrefsCache.put(packageName, packagePrefs);
         }
 
         return packagePrefs;
@@ -492,6 +509,7 @@
         if (!file.exists()) {
             try {
                 Os.mkdir(file.getAbsolutePath(), 0771);
+                Os.chmod(file.getAbsolutePath(), 0771);
             } catch (ErrnoException e) {
                 if (e.errno == OsConstants.EEXIST) {
                     // We must have raced with someone; that's okay
@@ -1405,25 +1423,35 @@
     public boolean bindService(Intent service, ServiceConnection conn,
             int flags) {
         warnIfCallingFromSystemProcess();
-        return bindServiceCommon(service, conn, flags, Process.myUserHandle());
+        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
+                Process.myUserHandle());
     }
 
     /** @hide */
     @Override
     public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
             UserHandle user) {
-        return bindServiceCommon(service, conn, flags, user);
+        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), user);
     }
 
-    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
-            UserHandle user) {
+    /** @hide */
+    @Override
+    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
+            Handler handler, UserHandle user) {
+        if (handler == null) {
+            throw new IllegalArgumentException("handler must not be null.");
+        }
+        return bindServiceCommon(service, conn, flags, handler, user);
+    }
+
+    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
+            handler, UserHandle user) {
         IServiceConnection sd;
         if (conn == null) {
             throw new IllegalArgumentException("connection is null");
         }
         if (mPackageInfo != null) {
-            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
-                    mMainThread.getHandler(), flags);
+            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
         } else {
             throw new RuntimeException("Not supported in system context");
         }
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index ed4bb28..1e5f007 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1193,13 +1193,52 @@
             boolean isMediaScannerScannable, String mimeType, String path, long length,
             boolean showNotification) {
         return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
-                length, showNotification, false);
+                length, showNotification, false, null, null);
+    }
+
+    /**
+     * Adds a file to the downloads database system, so it could appear in Downloads App
+     * (and thus become eligible for management by the Downloads App).
+     * <p>
+     * It is helpful to make the file scannable by MediaScanner by setting the param
+     * isMediaScannerScannable to true. It makes the file visible in media managing
+     * applications such as Gallery App, which could be a useful purpose of using this API.
+     *
+     * @param title the title that would appear for this file in Downloads App.
+     * @param description the description that would appear for this file in Downloads App.
+     * @param isMediaScannerScannable true if the file is to be scanned by MediaScanner. Files
+     * scanned by MediaScanner appear in the applications used to view media (for example,
+     * Gallery app).
+     * @param mimeType mimetype of the file.
+     * @param path absolute pathname to the file. The file should be world-readable, so that it can
+     * be managed by the Downloads App and any other app that is used to read it (for example,
+     * Gallery app to display the file, if the file contents represent a video/image).
+     * @param length length of the downloaded file
+     * @param showNotification true if a notification is to be sent, false otherwise
+     * @param uri the original HTTP URI of the download
+     * @param referer the HTTP Referer for the download
+     * @return  an ID for the download entry added to the downloads app, unique across the system
+     * This ID is used to make future calls related to this download.
+     */
+    public long addCompletedDownload(String title, String description,
+            boolean isMediaScannerScannable, String mimeType, String path, long length,
+            boolean showNotification, Uri uri, Uri referer) {
+        return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
+                length, showNotification, false, uri, referer);
     }
 
     /** {@hide} */
     public long addCompletedDownload(String title, String description,
             boolean isMediaScannerScannable, String mimeType, String path, long length,
             boolean showNotification, boolean allowWrite) {
+        return addCompletedDownload(title, description, isMediaScannerScannable, mimeType, path,
+                length, showNotification, allowWrite, null, null);
+    }
+
+    /** {@hide} */
+    public long addCompletedDownload(String title, String description,
+            boolean isMediaScannerScannable, String mimeType, String path, long length,
+            boolean showNotification, boolean allowWrite, Uri uri, Uri referer) {
         // make sure the input args are non-null/non-zero
         validateArgumentIsNonEmpty("title", title);
         validateArgumentIsNonEmpty("description", description);
@@ -1210,10 +1249,18 @@
         }
 
         // if there is already an entry with the given path name in downloads.db, return its id
-        Request request = new Request(NON_DOWNLOADMANAGER_DOWNLOAD)
-                .setTitle(title)
+        Request request;
+        if (uri != null) {
+            request = new Request(uri);
+        } else {
+            request = new Request(NON_DOWNLOADMANAGER_DOWNLOAD);
+        }
+        request.setTitle(title)
                 .setDescription(description)
                 .setMimeType(mimeType);
+        if (referer != null) {
+            request.addRequestHeader("Referer", referer.toString());
+        }
         ContentValues values = request.toContentValues(null);
         values.put(Downloads.Impl.COLUMN_DESTINATION,
                 Downloads.Impl.DESTINATION_NON_DOWNLOADMANAGER_DOWNLOAD);
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index fe9cc80..ddd0ae9 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -263,6 +263,7 @@
                 mViewsReadyListener = null;
             }
             showViews(mTransitioningViews, true);
+            setTransitioningViewsVisiblity(View.VISIBLE, true);
             mSharedElements.clear();
             mAllSharedElementNames.clear();
             mTransitioningViews.clear();
@@ -280,6 +281,7 @@
             if (!mIsViewsTransitionStarted) {
                 mIsViewsTransitionStarted = true;
                 showViews(mTransitioningViews, true);
+                setTransitioningViewsVisiblity(View.VISIBLE, true);
                 mTransitioningViews.clear();
                 viewsTransitionComplete();
             }
@@ -506,7 +508,6 @@
             if (viewsTransition == null) {
                 viewsTransitionComplete();
             } else {
-                viewsTransition.forceVisibility(View.INVISIBLE, true);
                 final ArrayList<View> transitioningViews = mTransitioningViews;
                 viewsTransition.addListener(new ContinueTransitionListener() {
                     @Override
@@ -532,12 +533,15 @@
         Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
         if (transition != null) {
             transition.addListener(new ContinueTransitionListener());
+            if (startEnterTransition) {
+                setTransitioningViewsVisiblity(View.INVISIBLE, false);
+            }
             TransitionManager.beginDelayedTransition(decorView, transition);
             if (startSharedElementTransition && !mSharedElementNames.isEmpty()) {
                 mSharedElements.get(0).invalidate();
-            } else if (startEnterTransition && mTransitioningViews != null &&
-                    !mTransitioningViews.isEmpty()) {
-                mTransitioningViews.get(0).invalidate();
+            }
+            if (startEnterTransition) {
+                setTransitioningViewsVisiblity(View.VISIBLE, true);
             }
         } else {
             transitionStarted();
@@ -613,6 +617,7 @@
         moveSharedElementsFromOverlay();
         if (mTransitioningViews != null) {
             showViews(mTransitioningViews, true);
+            setTransitioningViewsVisiblity(View.VISIBLE, true);
         }
         showViews(mSharedElements, true);
         clearState();
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index e93b40e..d54ffa0 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -48,27 +48,16 @@
     private static final long MAX_WAIT_MS = 1000;
 
     private Bundle mSharedElementBundle;
-
     private boolean mExitNotified;
-
     private boolean mSharedElementNotified;
-
     private Activity mActivity;
-
     private boolean mIsBackgroundReady;
-
     private boolean mIsCanceled;
-
     private Handler mHandler;
-
     private ObjectAnimator mBackgroundAnimator;
-
     private boolean mIsHidden;
-
     private Bundle mExitSharedElementBundle;
-
     private boolean mIsExitStarted;
-
     private boolean mSharedElementsHidden;
 
     public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
@@ -129,6 +118,7 @@
     public void resetViews() {
         if (mTransitioningViews != null) {
             showViews(mTransitioningViews, true);
+            setTransitioningViewsVisiblity(View.VISIBLE, true);
         }
         showViews(mSharedElements, true);
         mIsHidden = true;
@@ -276,8 +266,9 @@
         Transition transition = getExitTransition();
         ViewGroup decorView = getDecor();
         if (transition != null && decorView != null && mTransitioningViews != null) {
+            setTransitioningViewsVisiblity(View.VISIBLE, false);
             TransitionManager.beginDelayedTransition(decorView, transition);
-            mTransitioningViews.get(0).invalidate();
+            setTransitioningViewsVisiblity(View.INVISIBLE, true);
         } else {
             transitionStarted();
         }
@@ -325,6 +316,7 @@
                     viewsTransitionComplete();
                     if (mIsHidden && transitioningViews != null) {
                         showViews(transitioningViews, true);
+                        setTransitioningViewsVisiblity(View.VISIBLE, true);
                     }
                     if (mSharedElementBundle != null) {
                         delayCancel();
@@ -332,7 +324,6 @@
                     super.onTransitionEnd(transition);
                 }
             });
-            viewsTransition.forceVisibility(View.INVISIBLE, false);
         }
         return viewsTransition;
     }
@@ -369,9 +360,15 @@
         if (transition != null && decorView != null) {
             setGhostVisibility(View.INVISIBLE);
             scheduleGhostVisibilityChange(View.INVISIBLE);
+            if (viewsTransition != null) {
+                setTransitioningViewsVisiblity(View.VISIBLE, false);
+            }
             TransitionManager.beginDelayedTransition(decorView, transition);
             scheduleGhostVisibilityChange(View.VISIBLE);
             setGhostVisibility(View.VISIBLE);
+            if (viewsTransition != null) {
+                setTransitioningViewsVisiblity(View.INVISIBLE, true);
+            }
             decorView.invalidate();
         } else {
             transitionStarted();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index f5e7d78..ca86c18 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -426,7 +426,7 @@
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
     public boolean startUserInBackground(int userid) throws RemoteException;
-    public boolean unlockUser(int userid, byte[] token) throws RemoteException;
+    public boolean unlockUser(int userid, byte[] token, byte[] secret) throws RemoteException;
     public int stopUser(int userid, boolean force, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
     public boolean isUserRunning(int userid, int flags) throws RemoteException;
@@ -597,6 +597,10 @@
 
     public boolean supportsLocalVoiceInteraction() throws RemoteException;
 
+    public void notifyPinnedStackAnimationEnded() throws RemoteException;
+
+    public void removeStack(int stackId) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -972,4 +976,6 @@
     int START_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 363;
     int STOP_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 364;
     int SUPPORTS_LOCAL_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 365;
+    int NOTIFY_PINNED_STACK_ANIMATION_ENDED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 366;
+    int REMOVE_STACK = IBinder.FIRST_CALL_TRANSACTION + 367;
 }
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 40e58af..3c8dfce 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -46,6 +46,7 @@
 
     void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
     boolean areNotificationsEnabledForPackage(String pkg, int uid);
+    boolean areNotificationsEnabled(String pkg);
 
     ParceledListSlice getTopics(String pkg, int uid);
     void setVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
@@ -54,7 +55,8 @@
     int getPriority(String pkg, int uid, in Notification.Topic topic);
     void setImportance(String pkg, int uid, in Notification.Topic topic, int importance);
     int getImportance(String pkg, int uid, in Notification.Topic topic);
-    boolean doesAppUseTopics(String pkg, int uid);
+    int getTopicImportance(String pkg, String topicId);
+    boolean doesUserUseTopics(String pkg, int uid);
     boolean hasBannedTopics(String pkg, int uid);
 
     // TODO: Remove this when callers have been migrated to the equivalent
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index fa11234..6432558 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -30,4 +30,9 @@
      * brought to the front or a new Intent is delivered to it.
      */
     void onPinnedActivityRestartAttempt();
+
+    /**
+     * Called whenever the pinned stack is done animating a resize.
+     */
+    void onPinnedStackAnimationEnded();
 }
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 9a88f2c..33fd1db 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1842,13 +1842,10 @@
      * @see UiAutomation
      */
     public UiAutomation getUiAutomation() {
-        if (mUiAutomationConnection != null) {
-            if (mUiAutomation == null) {
-                return getUiAutomation(0);
-            }
-            return mUiAutomation;
+        if ((mUiAutomation == null) || (mUiAutomation.isDestroyed())) {
+            return getUiAutomation(0);
         }
-        return null;
+        return mUiAutomation;
     }
 
     /**
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index da52c1e..8717353 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -447,7 +447,8 @@
         IPackageManager pm = ActivityThread.getPackageManager();
         android.content.pm.PackageInfo pi;
         try {
-            pi = pm.getPackageInfo(mPackageName, 0, UserHandle.myUserId());
+            pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                    UserHandle.myUserId());
         } catch (RemoteException e) {
             throw new IllegalStateException("Unable to get package info for "
                     + mPackageName + "; is system dying?", e);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a78076b..35b7c39 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -51,6 +51,7 @@
 import android.view.Gravity;
 import android.view.NotificationHeaderView;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
 
@@ -3281,6 +3282,10 @@
                     validRemoteInput |= hasValidRemoteInput(action);
 
                     final RemoteViews button = generateActionButton(action);
+                    if (i == N - 1) {
+                        button.setViewLayoutWidth(com.android.internal.R.id.action0,
+                                ViewGroup.LayoutParams.MATCH_PARENT);
+                    }
                     big.addView(R.id.actions, button);
                 }
             }
@@ -3353,13 +3358,9 @@
                 return mN.bigContentView;
             } else if (mStyle != null) {
                 result = mStyle.makeBigContentView();
-            } else if (mActions.size() == 0) {
-                return null;
-            }
-            if (result == null) {
-                result = applyStandardTemplateWithActions(getBigBaseLayoutResource());
-            } else {
                 hideLine1Text(result);
+            } else if (mActions.size() != 0) {
+                result = applyStandardTemplateWithActions(getBigBaseLayoutResource());
             }
             adaptNotificationHeaderForBigContentView(result);
             return result;
@@ -3379,11 +3380,15 @@
         }
 
         private void hideLine1Text(RemoteViews result) {
-            result.setViewVisibility(R.id.text_line_1, View.GONE);
+            if (result != null) {
+                result.setViewVisibility(R.id.text_line_1, View.GONE);
+            }
         }
 
         private void adaptNotificationHeaderForBigContentView(RemoteViews result) {
-            result.setBoolean(R.id.notification_header, "setExpanded", true);
+            if (result != null) {
+                result.setBoolean(R.id.notification_header, "setExpanded", true);
+            }
         }
 
         /**
@@ -4321,6 +4326,15 @@
             return makeMediaBigContentView();
         }
 
+        /**
+         * @hide
+         */
+        @Override
+        public RemoteViews makeHeadsUpContentView() {
+            RemoteViews expanded = makeMediaBigContentView();
+            return expanded != null ? expanded : makeMediaContentView();
+        }
+
         /** @hide */
         @Override
         public void addExtras(Bundle extras) {
@@ -4402,6 +4416,13 @@
 
         private RemoteViews makeMediaBigContentView() {
             final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
+            // Dont add an expanded view if there is no more content to be revealed
+            int actionsInCompact = mActionsToShowInCompact == null
+                    ? 0
+                    : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
+            if (mBuilder.mN.mLargeIcon == null && actionCount <= actionsInCompact) {
+                return null;
+            }
             RemoteViews big = mBuilder.applyStandardTemplate(
                     R.layout.notification_template_material_big_media,
                     false);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index a83225d..1f17024 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import com.android.internal.util.Preconditions;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -37,6 +39,7 @@
 import android.os.UserHandle;
 import android.provider.Settings.Global;
 import android.service.notification.IConditionListener;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.util.ArraySet;
@@ -503,6 +506,25 @@
         return false;
     }
 
+    public int getImportance(String topicId) {
+        Preconditions.checkNotNull(topicId);
+        INotificationManager service = getService();
+        try {
+            return service.getTopicImportance(mContext.getPackageName(), topicId);
+        } catch (RemoteException e) {
+        }
+        return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+    }
+
+    public boolean areNotificationsEnabled() {
+        INotificationManager service = getService();
+        try {
+            return service.areNotificationsEnabled(mContext.getPackageName());
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
     /**
      * Checks the ability to read/modify notification policy for the calling package.
      *
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index c7d2140..a952915 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -363,7 +363,8 @@
         String suggestProviderPackage = null;
         if (mSuggestAuthority != null) {
             PackageManager pm = activityContext.getPackageManager();
-            ProviderInfo pi = pm.resolveContentProvider(mSuggestAuthority, 0);
+            ProviderInfo pi = pm.resolveContentProvider(mSuggestAuthority,
+                    PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
             if (pi != null) {
                 suggestProviderPackage = pi.packageName;
             }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 02eb115..7e7c5ec 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -16,12 +16,14 @@
 
 package android.app.admin;
 
+import android.annotation.ColorInt;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.auditing.SecurityLog;
 import android.auditing.SecurityLog.SecurityEvent;
@@ -1031,9 +1033,18 @@
      * @hide
      */
     public boolean packageHasActiveAdmins(String packageName) {
+        return packageHasActiveAdmins(packageName, myUserId());
+    }
+
+    /**
+     * Used by package administration code to determine if a package can be stopped
+     * or uninstalled.
+     * @hide
+     */
+    public boolean packageHasActiveAdmins(String packageName, int userId) {
         if (mService != null) {
             try {
-                return mService.packageHasActiveAdmins(packageName, myUserId());
+                return mService.packageHasActiveAdmins(packageName, userId);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -1826,9 +1837,23 @@
      * this method; if it has not, a security exception will be thrown.
      */
     public int getCurrentFailedPasswordAttempts() {
+        return getCurrentFailedPasswordAttempts(myUserId());
+    }
+
+    /**
+     * Retrieve the number of times the given user has failed at entering a
+     * password since that last successful password entry.
+     *
+     * <p>The calling device admin must have requested
+     * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to be able to call this method; if it has
+     * not and it is not the system uid, a security exception will be thrown.
+     *
+     * @hide
+     */
+    public int getCurrentFailedPasswordAttempts(int userHandle) {
         if (mService != null) {
             try {
-                return mService.getCurrentFailedPasswordAttempts(myUserId(), mParentInstance);
+                return mService.getCurrentFailedPasswordAttempts(userHandle, mParentInstance);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -2570,6 +2595,11 @@
      * Delegated certificate installer is a per-user state. The delegated access is persistent until
      * it is later cleared by calling this method with a null value or uninstallling the certificate
      * installer.
+     *<p>
+     * <b>Note:</b>Starting from {@link android.os.Build.VERSION_CODES#N}, if the caller
+     * application's target SDK version is {@link android.os.Build.VERSION_CODES#N} or newer, the
+     * supplied certificate installer package must be installed when calling this API,
+     * otherwise an {@link IllegalArgumentException} will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param installerPackage The package name of the certificate installer which will be given
@@ -3018,13 +3048,39 @@
     }
 
     /**
+     * @hide
+     */
+    public void reportFailedFingerprintAttempt(int userHandle) {
+        if (mService != null) {
+            try {
+                mService.reportFailedFingerprintAttempt(userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void reportSuccessfulFingerprintAttempt(int userHandle) {
+        if (mService != null) {
+            try {
+                mService.reportSuccessfulFingerprintAttempt(userHandle);
+            } catch (RemoteException e) {
+                Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+            }
+        }
+    }
+
+    /**
      * Should be called when keyguard has been dismissed.
      * @hide
      */
-    public void reportKeyguardDismissed() {
+    public void reportKeyguardDismissed(int userHandle) {
         if (mService != null) {
             try {
-                mService.reportKeyguardDismissed();
+                mService.reportKeyguardDismissed(userHandle);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -3035,10 +3091,10 @@
      * Should be called when keyguard view has been shown to the user.
      * @hide
      */
-    public void reportKeyguardSecured() {
+    public void reportKeyguardSecured(int userHandle) {
         if (mService != null) {
             try {
-                mService.reportKeyguardSecured();
+                mService.reportKeyguardSecured(userHandle);
             } catch (RemoteException e) {
                 Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
             }
@@ -3425,27 +3481,31 @@
     }
 
     /**
-     * Called by device or profile owners for setting the package suspended for this user.
-     * A suspended package will not be started by the package manager, its notifications will
-     * be hidden and it will not show up in recents. The package must already be installed.
+     * Called by device or profile owners to suspend packages for this user.
+     *
+     * <p>A suspended package will not be able to start activities. Its notifications will
+     * be hidden, it will not show up in recents, will not be able to show toasts or dialogs
+     * or ring the device.
+     *
+     * <p>The package must already be installed.
      *
      * @param admin The name of the admin component to check.
-     * @param packageName The package name of the app to suspend or unsuspend.
-     * @param suspended If set to {@code true} than the package will be suspended, if set to
-     * {@code false} the package will be unsuspended.
-     * @return boolean {@code true} if the operation was successfully performed, {@code false}
-     * otherwise.
+     * @param packageNames The package names to suspend or unsuspend.
+     * @param suspended If set to {@code true} than the packages will be suspended, if set to
+     * {@code false} the packages will be unsuspended.
+     * @return an array of package names for which the suspended status is not set as requested in
+     * this method.
      */
-    public boolean setPackageSuspended(@NonNull ComponentName admin, String packageName,
+    public String[] setPackagesSuspended(@NonNull ComponentName admin, String[] packageNames,
             boolean suspended) {
         if (mService != null) {
             try {
-                return mService.setPackageSuspended(admin, packageName, suspended);
+                return mService.setPackagesSuspended(admin, packageNames, suspended);
             } catch (RemoteException re) {
                 Log.w(TAG, "Failed talking with device policy service", re);
             }
         }
-        return false;
+        return packageNames;
     }
 
     /**
@@ -3453,7 +3513,8 @@
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The name of the package to retrieve the suspended status of.
-     * @return boolean {@code true} if the package is suspended, {@code false} otherwise.
+     * @return {@code true} if the package is suspended or {@code false} if the package is not
+     * suspended, could not be found or an error occurred.
      */
     public boolean getPackageSuspended(@NonNull ComponentName admin, String packageName) {
         if (mService != null) {
@@ -3650,6 +3711,9 @@
      * <p>
      * This permission is persistent until it is later cleared by calling this method with a
      * {@code null} value or uninstalling the managing package.
+     * <p>
+     * The supplied application restriction managing package must be installed when calling this
+     * API, otherwise an {@link IllegalArgumentException} will be thrown.
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      * @param packageName The package name which will be given access to application restrictions
@@ -5564,6 +5628,25 @@
     }
 
     /**
+     * @hide
+     *
+     * Sets the color used for customization.
+     *
+     * @param color The 32bit representation of the color to be used.
+     * @param userId which user to set the color to.
+     * @RequiresPermission(allOf = {
+     *       Manifest.permission.MANAGE_USERS,
+     *       Manifest.permission.INTERACT_ACROSS_USERS_FULL})
+     */
+    public void setOrganizationColorForUser(@ColorInt int color, @UserIdInt int userId) {
+        try {
+            mService.setOrganizationColorForUser(color, userId);
+        } catch (RemoteException re) {
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+        }
+    }
+
+    /**
      * Called by a profile owner of a managed profile to retrieve the color used for customization.
      * This color is used as background color of the confirm credentials screen for that user.
      *
@@ -5722,4 +5805,32 @@
             return false;
         }
     }
+
+    /**
+     * @hide
+     * Returns whether the uninstall for {@code packageName} for the current user is in queue
+     * to be started
+     * @param packageName the package to check for
+     * @return whether the uninstall intent for {@code packageName} is pending
+     */
+    public boolean isUninstallInQueue(String packageName) {
+        try {
+            return mService.isUninstallInQueue(packageName);
+        } catch (RemoteException re) {
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+            return false;
+        }
+    }
+
+    /**
+     * @hide
+     * @param packageName the package containing active DAs to be uninstalled
+     */
+    public void uninstallPackageWithActiveAdmins(String packageName) {
+        try {
+            mService.uninstallPackageWithActiveAdmins(packageName);
+        } catch (RemoteException re) {
+            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index c6a5344..e9af872 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -116,9 +116,10 @@
         int numbers, int symbols, int nonletter, int userHandle);
     void reportFailedPasswordAttempt(int userHandle);
     void reportSuccessfulPasswordAttempt(int userHandle);
-
-    void reportKeyguardDismissed();
-    void reportKeyguardSecured();
+    void reportFailedFingerprintAttempt(int userHandle);
+    void reportSuccessfulFingerprintAttempt(int userHandle);
+    void reportKeyguardDismissed(int userHandle);
+    void reportKeyguardSecured(int userHandle);
 
     boolean setDeviceOwner(in ComponentName who, String ownerName, int userId);
     ComponentName getDeviceOwnerComponent(boolean callingUserOnly);
@@ -137,7 +138,7 @@
     boolean setDeviceOwnerLockScreenInfo(in ComponentName who, String deviceOwnerInfo);
     String getDeviceOwnerLockScreenInfo();
 
-    boolean setPackageSuspended(in ComponentName admin, String packageName, boolean suspended);
+    String[] setPackagesSuspended(in ComponentName admin, in String[] packageNames, boolean suspended);
     boolean getPackageSuspended(in ComponentName admin, String packageName);
 
     boolean installCaCert(in ComponentName admin, in byte[] certBuffer);
@@ -276,6 +277,7 @@
     boolean isSeparateProfileChallengeAllowed(int userHandle);
 
     void setOrganizationColor(in ComponentName admin, in int color);
+    void setOrganizationColorForUser(in int color, in int userId);
     int getOrganizationColor(in ComponentName admin);
     int getOrganizationColorForUser(int userHandle);
 
@@ -293,4 +295,7 @@
     boolean getDeviceLoggingEnabled(in ComponentName admin);
     ParceledListSlice retrieveDeviceLogs(in ComponentName admin);
     ParceledListSlice retrievePreviousDeviceLogs(in ComponentName admin);
+
+    boolean isUninstallInQueue(String packageName);
+    void uninstallPackageWithActiveAdmins(String packageName);
 }
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index ac23b68..da81d19 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -501,7 +501,7 @@
      * @param packageName ID of package to provide the quota.
      * @param isFullBackup If set, transport should return limit for full data backup, otherwise
      *                     for key-value backup.
-     * @return Current limit on full data backup size in bytes.
+     * @return Current limit on backup size in bytes.
      */
     public long getBackupQuota(String packageName, boolean isFullBackup) {
         return Long.MAX_VALUE;
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index bed91ec..cd8f126 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -376,7 +376,13 @@
      * AppWidget provider. Will animate into these new views as needed
      */
     public void updateAppWidget(RemoteViews remoteViews) {
+        applyRemoteViews(remoteViews);
+    }
 
+    /**
+     * @hide
+     */
+    protected void applyRemoteViews(RemoteViews remoteViews) {
         if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld);
 
         boolean recycled = false;
@@ -573,8 +579,9 @@
     /**
      * Build a {@link Context} cloned into another package name, usually for the
      * purposes of reading remote resources.
+     * @hide
      */
-    private Context getRemoteContext() {
+    protected Context getRemoteContext() {
         try {
             // Return if cloned successfully, otherwise default
             return mContext.createApplicationContext(
diff --git a/core/java/android/auditing/SecurityLog.java b/core/java/android/auditing/SecurityLog.java
index 8d8d2f5..f1703d6 100644
--- a/core/java/android/auditing/SecurityLog.java
+++ b/core/java/android/auditing/SecurityLog.java
@@ -77,8 +77,10 @@
             SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;
     /**
      * Indicate that there has been an authentication attempt to dismiss the keyguard. The log entry
-     * contains the attempt result (integer, 1 for successful, 0 for unsuccessful), accessible via
-     * {@link SecurityEvent#getData()}}
+     * contains the following information about the attempt in order, accessible via
+     * {@link SecurityEvent#getData()}}: attempt result (integer, 1 for successful, 0 for
+     * unsuccessful), strength of auth method (integer, 1 if strong auth method was used,
+     * 0 otherwise)
      */
     public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT =
             SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT;
diff --git a/core/java/android/auditing/SecurityLogTags.logtags b/core/java/android/auditing/SecurityLogTags.logtags
index cf85894..ccc3799 100644
--- a/core/java/android/auditing/SecurityLogTags.logtags
+++ b/core/java/android/auditing/SecurityLogTags.logtags
@@ -8,5 +8,5 @@
 210004 security_adb_sync_send                   (path|3)
 210005 security_app_process_start               (process|3),(start_time|2|3),(uid|1),(pid|1),(seinfo|3),(sha256|3)
 210006 security_keyguard_dismissed
-210007 security_keyguard_dismiss_auth_attempt   (success|1)
+210007 security_keyguard_dismiss_auth_attempt   (success|1),(method_strength|1)
 210008 security_keyguard_secured
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 4918914..fff0c14 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2534,6 +2534,17 @@
     }
 
     /**
+     * Same as {@link #bindService(Intent, ServiceConnection, int, UserHandle)}, but with an
+     * explicit non-null Handler to run the ServiceConnection callbacks on.
+     *
+     * @hide
+     */
+    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
+            Handler handler, UserHandle user) {
+        throw new RuntimeException("Not implemented. Must override in a subclass.");
+    }
+
+    /**
      * Disconnect from an application service.  You will no longer receive
      * calls as the service is restarted, and the service is now allowed to
      * stop at any time.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7dc7401..8f2b9c8 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3028,6 +3028,17 @@
             "android.intent.action.MANAGED_PROFILE_REMOVED";
 
     /**
+     * Broadcast sent to the primary user when the credential-encrypted private storage for
+     * an associated managed profile is unlocked. Carries an extra {@link #EXTRA_USER} that
+     * specifies the UserHandle of the profile that was unlocked. Only applications (for example
+     * Launchers) that need to display merged content across both primary and managed profiles
+     * need to worry about this broadcast. This is only sent to registered receivers,
+     * not manifest receivers.
+     */
+    public static final String ACTION_MANAGED_PROFILE_UNLOCKED =
+            "android.intent.action.MANAGED_PROFILE_UNLOCKED";
+
+    /**
      * Broadcast sent to the primary user when an associated managed profile's availability has
      * changed. This includes when the user toggles the profile's quiet mode. Carries an extra
      * {@link #EXTRA_USER} that specifies the UserHandle of the profile. When quiet mode is changed,
@@ -3176,38 +3187,6 @@
             ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
 
     /**
-     * Activity Action: Give access to a standard storage directory after obtaining the user's
-     * approval.
-     * <p>
-     * When invoked, the system will ask the user to grant access to the requested directory (and
-     * its descendants).
-     * <p>
-     * To gain access to descendant (child, grandchild, etc) documents, use
-     * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)} and
-     * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI.
-     * <p>
-     * Input: full path to a standard directory, in the form of
-     * {@code STORAGE_ROOT + STANDARD_DIRECTORY}, where {@code STORAGE_ROOT} is the physical path of
-     * a storage container, and {@code STANDARD_DIRECTORY} is one of
-     * {@link Environment#DIRECTORY_MUSIC}, {@link Environment#DIRECTORY_PODCASTS},
-     * {@link Environment#DIRECTORY_RINGTONES}, {@link Environment#DIRECTORY_ALARMS},
-     * {@link Environment#DIRECTORY_NOTIFICATIONS}, {@link Environment#DIRECTORY_PICTURES},
-     * {@link Environment#DIRECTORY_MOVIES}, {@link Environment#DIRECTORY_DOWNLOADS},
-     * {@link Environment#DIRECTORY_DCIM}, or {@link Environment#DIRECTORY_DOCUMENTS}
-     * <p>
-     * For example, to open the "Pictures" folder in the default external storage, the intent's data
-     * would be: {@code Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
-     * Environment.DIRECTORY_PICTURES))}.
-     * <p>
-     * Output: The URI representing the requested directory tree.
-     *
-     * @see DocumentsContract
-     */
-    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String
-            ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
-
-    /**
      * Broadcast Action: List of dynamic sensor is changed due to new sensor being connected or
      * exisiting sensor being disconnected.
      *
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 43a0cc7..14ef61c 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -178,6 +178,11 @@
      */
     public static final int RESIZE_MODE_RESIZEABLE_AND_PIPABLE = 3;
     /**
+     * Activity is does not support resizing, but we are forcing it to be resizeable.
+     * @hide
+     */
+    public static final int RESIZE_MODE_FORCE_RESIZEABLE = 4;
+    /**
      * Value indicating if the resizing mode the activity supports.
      * See {@link android.R.attr#resizeableActivity}.
      * @hide
@@ -784,9 +789,27 @@
         }
     }
 
+    /**
+     * Returns true if the activity's orientation is fixed.
+     * @hide
+     */
+    boolean isFixedOrientation() {
+        return screenOrientation == SCREEN_ORIENTATION_LANDSCAPE
+                || screenOrientation == SCREEN_ORIENTATION_PORTRAIT
+                || screenOrientation == SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+                || screenOrientation == SCREEN_ORIENTATION_SENSOR_PORTRAIT
+                || screenOrientation == SCREEN_ORIENTATION_REVERSE_LANDSCAPE
+                || screenOrientation == SCREEN_ORIENTATION_REVERSE_PORTRAIT
+                || screenOrientation == SCREEN_ORIENTATION_USER_LANDSCAPE
+                || screenOrientation == SCREEN_ORIENTATION_USER_PORTRAIT
+                || screenOrientation == SCREEN_ORIENTATION_LOCKED;
+    }
+
     /** @hide */
     public static boolean isResizeableMode(int mode) {
-        return mode == RESIZE_MODE_RESIZEABLE || mode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
+        return mode == RESIZE_MODE_RESIZEABLE
+                || mode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE
+                || mode == RESIZE_MODE_FORCE_RESIZEABLE;
     }
 
     /** @hide */
@@ -800,6 +823,8 @@
                 return "RESIZE_MODE_RESIZEABLE";
             case RESIZE_MODE_RESIZEABLE_AND_PIPABLE:
                 return "RESIZE_MODE_RESIZEABLE_AND_PIPABLE";
+            case RESIZE_MODE_FORCE_RESIZEABLE:
+                return "RESIZE_MODE_FORCE_RESIZEABLE";
             default:
                 return "unknown=" + mode;
         }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1fea665..9082482 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -181,7 +181,7 @@
     public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
     
     /**
-     * Value for {@link #flags}: this is set of the application has specified
+     * Value for {@link #flags}: this is set if the application has specified
      * {@link android.R.styleable#AndroidManifestApplication_testOnly
      * android:testOnly} to be true.
      */
@@ -1038,10 +1038,10 @@
         }
 
         deviceEncryptedDataDir = Environment
-                .getDataUserDeviceEncryptedPackageDirectory(volumeUuid, userId, packageName)
+                .getDataUserDePackageDirectory(volumeUuid, userId, packageName)
                 .getAbsolutePath();
         credentialEncryptedDataDir = Environment
-                .getDataUserCredentialEncryptedPackageDirectory(volumeUuid, userId, packageName)
+                .getDataUserCePackageDirectory(volumeUuid, userId, packageName)
                 .getAbsolutePath();
 
         if ((privateFlags & PRIVATE_FLAG_FORCE_DEVICE_ENCRYPTED) != 0
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 79fa327..7671f72 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -20,9 +20,18 @@
 import android.os.Parcelable;
 
 /**
- * A single feature that can be requested by an application. This corresponds
- * to information collected from the
- * AndroidManifest.xml's {@code <uses-feature>} tag.
+ * Definition of a single optional hardware or software feature of an Android
+ * device.
+ * <p>
+ * This object is used to represent both features supported by a device and
+ * features requested by an app. Apps can request that certain features be
+ * available as a prerequisite to being installed through the
+ * {@code uses-feature} tag in their manifests.
+ * <p>
+ * Starting in {@link android.os.Build.VERSION_CODES#N}, features can have a
+ * version, which must always be backwards compatible. That is, a device
+ * claiming to support version 3 of a specific feature must support apps
+ * requesting version 1 of that feature.
  */
 public class FeatureInfo implements Parcelable {
     /**
@@ -31,7 +40,17 @@
      * in {@link #reqGlEsVersion}.
      */
     public String name;
-    
+
+    /**
+     * If this object represents a feature supported by a device, this is the
+     * maximum version of this feature supported by the device. The device
+     * implicitly supports all older versions of this feature.
+     * <p>
+     * If this object represents a feature requested by an app, this is the
+     * minimum version of the feature required by the app.
+     */
+    public int version;
+
     /**
      * Default value for {@link #reqGlEsVersion};
      */
@@ -59,15 +78,17 @@
 
     public FeatureInfo(FeatureInfo orig) {
         name = orig.name;
+        version = orig.version;
         reqGlEsVersion = orig.reqGlEsVersion;
         flags = orig.flags;
     }
 
+    @Override
     public String toString() {
         if (name != null) {
             return "FeatureInfo{"
                     + Integer.toHexString(System.identityHashCode(this))
-                    + " " + name + " fl=0x" + Integer.toHexString(flags) + "}";
+                    + " " + name + " v=" + version + " fl=0x" + Integer.toHexString(flags) + "}";
         } else {
             return "FeatureInfo{"
                     + Integer.toHexString(System.identityHashCode(this))
@@ -76,21 +97,25 @@
         }
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         dest.writeString(name);
+        dest.writeInt(version);
         dest.writeInt(reqGlEsVersion);
         dest.writeInt(flags);
     }
 
-    public static final Creator<FeatureInfo> CREATOR =
-        new Creator<FeatureInfo>() {
+    public static final Creator<FeatureInfo> CREATOR = new Creator<FeatureInfo>() {
+        @Override
         public FeatureInfo createFromParcel(Parcel source) {
             return new FeatureInfo(source);
         }
+        @Override
         public FeatureInfo[] newArray(int size) {
             return new FeatureInfo[size];
         }
@@ -98,6 +123,7 @@
 
     private FeatureInfo(Parcel source) {
         name = source.readString();
+        version = source.readInt();
         reqGlEsVersion = source.readInt();
         flags = source.readInt();
     }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 593fe2a..d6b674c 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -283,7 +283,8 @@
 
     void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage);
 
-    boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId);
+    String[] setPackagesSuspendedAsUser(in String[] packageNames, boolean suspended, int userId);
+    boolean isPackageSuspendedForUser(String packageName, int userId);
 
     /**
      * Backup/restore support - only the system uid may use these.
@@ -416,7 +417,7 @@
      */
     FeatureInfo[] getSystemAvailableFeatures();
 
-    boolean hasSystemFeature(String name);
+    boolean hasSystemFeature(String name, int version);
 
     void enterSafeMode();
     boolean isSafeMode();
@@ -534,4 +535,8 @@
     boolean isEphemeralApplication(String packageName, int userId);
 
     boolean setRequiredForSystemUser(String packageName, boolean systemUserApp);
+
+    String getServicesSystemSharedLibraryPackageName();
+
+    boolean isPackageDeviceAdminOnAnyUser(String packageName);
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index aac0043..0967608 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1233,6 +1233,14 @@
     public static final int MOVE_FAILED_OPERATION_PENDING = -7;
 
     /**
+     * Error code that is passed to the {@link IPackageMoveObserver} if the
+     * specified package cannot be moved since it contains a device admin.
+     *
+     * @hide
+     */
+    public static final int MOVE_FAILED_DEVICE_ADMIN = -8;
+
+    /**
      * Flag parameter for {@link #movePackage} to indicate that
      * the package should be moved to internal storage if its
      * been installed on external media.
@@ -2327,6 +2335,28 @@
     public static final int MASK_PERMISSION_FLAGS = 0xFF;
 
     /**
+     * This is a library that contains components apps can invoke. For
+     * example, a services for apps to bind to, or standard chooser UI,
+     * etc. This library is versioned and backwards compatible. Clients
+     * should check its version via {@link android.ext.services.Version
+     * #getVersionCode()} and avoid calling APIs added in later versions.
+     *
+     * @hide
+     */
+    public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
+
+    /**
+     * This is a library that contains components apps can dynamically
+     * load. For example, new widgets, helper classes, etc. This library
+     * is versioned and backwards compatible. Clients should check its
+     * version via {@link android.ext.shared.Version#getVersionCode()}
+     * and avoid calling APIs added in later versions.
+     *
+     * @hide
+     */
+    public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
+
+    /**
      * Retrieve overall information about an application package that is
      * installed on the system.
      *
@@ -3365,6 +3395,15 @@
     public abstract String[] getSystemSharedLibraryNames();
 
     /**
+     * Get the name of the package hosting the services shared library.
+     *
+     * @return The library host package.
+     *
+     * @hide
+     */
+    public abstract @Nullable String getServicesSystemSharedLibraryPackageName();
+
+    /**
      * Get a list of features that are available on the
      * system.
      *
@@ -3374,15 +3413,27 @@
     public abstract FeatureInfo[] getSystemAvailableFeatures();
 
     /**
-     * Check whether the given feature name is one of the available
-     * features as returned by {@link #getSystemAvailableFeatures()}.
+     * Check whether the given feature name is one of the available features as
+     * returned by {@link #getSystemAvailableFeatures()}. This tests for the
+     * presence of <em>any</em> version of the given feature name; use
+     * {@link #hasSystemFeature(String, int)} to check for a minimum version.
      *
-     * @return Returns true if the devices supports the feature, else
-     * false.
+     * @return Returns true if the devices supports the feature, else false.
      */
     public abstract boolean hasSystemFeature(String name);
 
     /**
+     * Check whether the given feature name and version is one of the available
+     * features as returned by {@link #getSystemAvailableFeatures()}. Since
+     * features are defined to always be backwards compatible, this returns true
+     * if the available feature version is greater than or equal to the
+     * requested version.
+     *
+     * @return Returns true if the devices supports the feature, else false.
+     */
+    public abstract boolean hasSystemFeature(String name, int version);
+
+    /**
      * Determine the best action to perform for a given Intent.  This is how
      * {@link Intent#resolveActivity} finds an activity if a class has not
      * been explicitly specified.
@@ -4489,7 +4540,7 @@
 
             PackageParser.Package pkg = parser.parseMonolithicPackage(apkFile, 0);
             if ((flags & GET_SIGNATURES) != 0) {
-                parser.collectCertificates(pkg, 0);
+                PackageParser.collectCertificates(pkg, 0);
             }
             PackageUserState state = new PackageUserState();
             return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null, state);
@@ -5259,19 +5310,34 @@
     public abstract boolean isSignedByExactly(String packageName, KeySet ks);
 
     /**
-     * Puts the package in a suspended state, making the package un-runnable,
-     * but it doesn't remove the data or the actual package file. The application notifications
-     * will be hidden and also the application will not show up in recents.
+     * Puts the package in a suspended state, where attempts at starting activities are denied.
      *
-     * @param packageName The name of the package to set the suspended status.
-     * @param suspended If set to {@code true} than the package will be suspended, if set to
-     * {@code false} the package will be unsuspended.
+     * <p>It doesn't remove the data or the actual package file. The application notifications
+     * will be hidden, the application will not show up in recents, will not be able to show
+     * toasts or dialogs or ring the device.
+     *
+     * @param packageNames The names of the packages to set the suspended status.
+     * @param suspended If set to {@code true} than the packages will be suspended, if set to
+     * {@code false} the packages will be unsuspended.
      * @param userId The user id.
      *
+     * @return an array of package names for which the suspended status is not set as requested in
+     * this method.
+     *
      * @hide
      */
-    public abstract boolean setPackageSuspendedAsUser(
-            String packageName, boolean suspended, @UserIdInt int userId);
+    public abstract String[] setPackagesSuspendedAsUser(
+            String[] packageNames, boolean suspended, @UserIdInt int userId);
+
+    /**
+     * @see #setPackageSuspendedAsUser(String, boolean, int)
+     * @param packageName The name of the package to get the suspended status of.
+     * @param userId The user id.
+     * @return {@code true} if the package is suspended or {@code false} if the package is not
+     * suspended or could not be found.
+     * @hide
+     */
+    public abstract boolean isPackageSuspendedForUser(String packageName, int userId);
 
     /** {@hide} */
     public static boolean isMoveStatusFinished(int status) {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3802db8..f6ae020 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -80,6 +80,7 @@
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
@@ -118,6 +119,8 @@
     private static final boolean DEBUG_PARSER = false;
     private static final boolean DEBUG_BACKUP = false;
 
+    private static final int MAX_PACKAGES_PER_APK = 5;
+
     // TODO: switch outError users to PackageParserException
     // TODO: refactor "codePath" to "apkPath"
 
@@ -133,6 +136,50 @@
     /** Path prefix for apps on expanded storage */
     private static final String MNT_EXPAND = "/mnt/expand/";
 
+    private static final String TAG_MANIFEST = "manifest";
+    private static final String TAG_APPLICATION = "application";
+    private static final String TAG_OVERLAY = "overlay";
+    private static final String TAG_KEY_SETS = "key-sets";
+    private static final String TAG_PERMISSION_GROUP = "permission-group";
+    private static final String TAG_PERMISSION = "permission";
+    private static final String TAG_PERMISSION_TREE = "permission-tree";
+    private static final String TAG_USES_PERMISSION = "uses-permission";
+    private static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m";
+    private static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23";
+    private static final String TAG_USES_CONFIGURATION = "uses-configuration";
+    private static final String TAG_USES_FEATURE = "uses-feature";
+    private static final String TAG_FEATURE_GROUP = "feature-group";
+    private static final String TAG_USES_SDK = "uses-sdk";
+    private static final String TAG_SUPPORT_SCREENS = "supports-screens";
+    private static final String TAG_PROTECTED_BROADCAST = "protected-broadcast";
+    private static final String TAG_INSTRUMENTATION = "instrumentation";
+    private static final String TAG_ORIGINAL_PACKAGE = "original-package";
+    private static final String TAG_ADOPT_PERMISSIONS = "adopt-permissions";
+    private static final String TAG_USES_GL_TEXTURE = "uses-gl-texture";
+    private static final String TAG_COMPATIBLE_SCREENS = "compatible-screens";
+    private static final String TAG_SUPPORTS_INPUT = "supports-input";
+    private static final String TAG_EAT_COMMENT = "eat-comment";
+    private static final String TAG_PACKAGE = "package";
+
+    // These are the tags supported by child packages
+    private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>();
+    static {
+        CHILD_PACKAGE_TAGS.add(TAG_APPLICATION);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_M);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_23);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE);
+        CHILD_PACKAGE_TAGS.add(TAG_FEATURE_GROUP);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_SDK);
+        CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS);
+        CHILD_PACKAGE_TAGS.add(TAG_INSTRUMENTATION);
+        CHILD_PACKAGE_TAGS.add(TAG_USES_GL_TEXTURE);
+        CHILD_PACKAGE_TAGS.add(TAG_COMPATIBLE_SCREENS);
+        CHILD_PACKAGE_TAGS.add(TAG_SUPPORTS_INPUT);
+        CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT);
+    }
+
     /** @hide */
     public static class NewPermissionInfo {
         public final String name;
@@ -291,7 +338,7 @@
 
         public final boolean coreApp;
         public final boolean multiArch;
-        public final String abiOverride;
+        public final boolean use32bitAbi;
         public final boolean extractNativeLibs;
 
         public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
@@ -308,7 +355,7 @@
             this.splitRevisionCodes = splitRevisionCodes;
             this.coreApp = baseApk.coreApp;
             this.multiArch = baseApk.multiArch;
-            this.abiOverride = baseApk.abiOverride;
+            this.use32bitAbi = baseApk.use32bitAbi;
             this.extractNativeLibs = baseApk.extractNativeLibs;
         }
 
@@ -336,12 +383,12 @@
         public final Signature[] signatures;
         public final boolean coreApp;
         public final boolean multiArch;
-        public final String abiOverride;
+        public final boolean use32bitAbi;
         public final boolean extractNativeLibs;
 
         public ApkLite(String codePath, String packageName, String splitName, int versionCode,
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
-                Signature[] signatures, boolean coreApp, boolean multiArch, String abiOverride,
+                Signature[] signatures, boolean coreApp, boolean multiArch, boolean use32bitAbi,
                 boolean extractNativeLibs) {
             this.codePath = codePath;
             this.packageName = packageName;
@@ -353,7 +400,7 @@
             this.signatures = signatures;
             this.coreApp = coreApp;
             this.multiArch = multiArch;
-            this.abiOverride = abiOverride;
+            this.use32bitAbi = use32bitAbi;
             this.extractNativeLibs = extractNativeLibs;
         }
     }
@@ -796,8 +843,8 @@
                 }
             }
 
-            pkg.codePath = packageDir.getAbsolutePath();
-            pkg.cpuAbiOverride = lite.abiOverride;
+            pkg.setCodePath(packageDir.getAbsolutePath());
+            pkg.setUse32bitAbi(lite.use32bitAbi);
             return pkg;
         } finally {
             IoUtils.closeQuietly(assets);
@@ -827,8 +874,8 @@
         final AssetManager assets = new AssetManager();
         try {
             final Package pkg = parseBaseApk(apkFile, assets, flags);
-            pkg.codePath = apkFile.getAbsolutePath();
-            pkg.cpuAbiOverride = lite.abiOverride;
+            pkg.setCodePath(apkFile.getAbsolutePath());
+            pkg.setUse32bitAbi(lite.use32bitAbi);
             return pkg;
         } finally {
             IoUtils.closeQuietly(assets);
@@ -885,10 +932,10 @@
                         apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
             }
 
-            pkg.volumeUuid = volumeUuid;
-            pkg.applicationInfo.volumeUuid = volumeUuid;
-            pkg.baseCodePath = apkPath;
-            pkg.mSignatures = null;
+            pkg.setVolumeUuid(volumeUuid);
+            pkg.setApplicationVolumeUuid(volumeUuid);
+            pkg.setBaseCodePath(apkPath);
+            pkg.setSignatures(null);
 
             return pkg;
 
@@ -951,7 +998,7 @@
         AttributeSet attrs = parser;
 
         // We parsed manifest tag earlier; just skip past it
-        parsePackageSplitNames(parser, attrs, flags);
+        parsePackageSplitNames(parser, attrs);
 
         mParseInstrumentationArgs = null;
         mParseActivityArgs = null;
@@ -984,7 +1031,7 @@
                 }
 
                 foundApp = true;
-                if (!parseSplitApplication(pkg, res, parser, attrs, flags, splitIndex, outError)) {
+                if (!parseSplitApplication(pkg, res, parser, flags, splitIndex, outError)) {
                     return null;
                 }
 
@@ -1016,7 +1063,18 @@
      * populating {@link Package#mSignatures}. Also asserts that all APK
      * contents are signed correctly and consistently.
      */
-    public void collectCertificates(Package pkg, int parseFlags) throws PackageParserException {
+    public static void collectCertificates(Package pkg, int parseFlags) throws PackageParserException {
+        collectCertificatesInternal(pkg, parseFlags);
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            Package childPkg = pkg.childPackages.get(i);
+            childPkg.mCertificates = pkg.mCertificates;
+            childPkg.mSignatures = pkg.mSignatures;
+            childPkg.mSigningKeys = pkg.mSigningKeys;
+        }
+    }
+
+    private static void collectCertificatesInternal(Package pkg, int parseFlags) throws PackageParserException {
         pkg.mCertificates = null;
         pkg.mSignatures = null;
         pkg.mSigningKeys = null;
@@ -1269,7 +1327,7 @@
     }
 
     private static Pair<String, String> parsePackageSplitNames(XmlPullParser parser,
-            AttributeSet attrs, int flags) throws IOException, XmlPullParserException,
+            AttributeSet attrs) throws IOException, XmlPullParserException,
             PackageParserException {
 
         int type;
@@ -1281,7 +1339,7 @@
             throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                     "No start tag found");
         }
-        if (!parser.getName().equals("manifest")) {
+        if (!parser.getName().equals(TAG_MANIFEST)) {
             throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                     "No <manifest> tag");
         }
@@ -1315,14 +1373,14 @@
     private static ApkLite parseApkLite(String codePath, Resources res, XmlPullParser parser,
             AttributeSet attrs, int flags, Signature[] signatures) throws IOException,
             XmlPullParserException, PackageParserException {
-        final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs, flags);
+        final Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs);
 
         int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
         int versionCode = 0;
         int revisionCode = 0;
         boolean coreApp = false;
         boolean multiArch = false;
-        String abiOverride = null;
+        boolean use32bitAbi = false;
         boolean extractNativeLibs = true;
 
         for (int i = 0; i < attrs.getAttributeCount(); i++) {
@@ -1363,8 +1421,8 @@
                     if ("multiArch".equals(attr)) {
                         multiArch = attrs.getAttributeBooleanValue(i, false);
                     }
-                    if ("abiOverride".equals(attr)) {
-                        abiOverride = attrs.getAttributeValue(i);
+                    if ("use32bitAbi".equals(attr)) {
+                        use32bitAbi = attrs.getAttributeBooleanValue(i, false);
                     }
                     if ("extractNativeLibs".equals(attr)) {
                         extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
@@ -1375,7 +1433,7 @@
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
                 revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
-                abiOverride, extractNativeLibs);
+                use32bitAbi, extractNativeLibs);
     }
 
     /**
@@ -1391,46 +1449,120 @@
     }
 
     /**
-     * Parse the manifest of a <em>base APK</em>.
-     * <p>
-     * When adding new features, carefully consider if they should also be
-     * supported by split APKs.
+     * Parses a child package and adds it to the parent if successful. If you add
+     * new tags that need to be supported by child packages make sure to add them
+     * to {@link #CHILD_PACKAGE_TAGS}.
+     *
+     * @param parentPkg The parent that contains the child
+     * @param res Resources against which to resolve values
+     * @param parser Parser of the manifest
+     * @param flags Flags about how to parse
+     * @param outError Human readable error if parsing fails
+     * @return True of parsing succeeded.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     */
+    private boolean parseBaseApkChild(Package parentPkg, Resources res, XmlResourceParser parser,
+            int flags, String[] outError) throws XmlPullParserException, IOException {
+        // Let ppl not abuse this mechanism by limiting the packages per APK
+        if (parentPkg.childPackages != null && parentPkg.childPackages.size() + 2
+                > MAX_PACKAGES_PER_APK) {
+            outError[0] = "Maximum number of packages per APK is: " + MAX_PACKAGES_PER_APK;
+            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+            return false;
+        }
+
+        // Make sure we have a valid child package name
+        String childPackageName = parser.getAttributeValue(null, "package");
+        if (validateName(childPackageName, true, false) != null) {
+            mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
+            return false;
+        }
+
+        // Child packages must be unique
+        if (childPackageName.equals(parentPkg.packageName)) {
+            String message = "Child package name cannot be equal to parent package name: "
+                    + parentPkg.packageName;
+            Slog.w(TAG, message);
+            outError[0] = message;
+            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+            return false;
+        }
+
+        // Child packages must be unique
+        if (parentPkg.hasChildPackage(childPackageName)) {
+            String message = "Duplicate child package:" + childPackageName;
+            Slog.w(TAG, message);
+            outError[0] = message;
+            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+            return false;
+        }
+
+        // Go ahead and parse the child
+        Package childPkg = new Package(childPackageName);
+
+        // Child package inherits parent version code/name/target SDK
+        childPkg.mVersionCode = parentPkg.mVersionCode;
+        childPkg.baseRevisionCode = parentPkg.baseRevisionCode;
+        childPkg.mVersionName = parentPkg.mVersionName;
+        childPkg.applicationInfo.targetSdkVersion = parentPkg.applicationInfo.targetSdkVersion;
+
+        childPkg = parseBaseApkCommon(childPkg, CHILD_PACKAGE_TAGS, res, parser, flags, outError);
+        if (childPkg == null) {
+            // If we got null then error was set during child parsing
+            return false;
+        }
+
+        // Set the parent-child relation
+        if (parentPkg.childPackages == null) {
+            parentPkg.childPackages = new ArrayList<>();
+        }
+        parentPkg.childPackages.add(childPkg);
+        childPkg.parentPackage = parentPkg;
+
+        return true;
+    }
+
+    /**
+     * Parse the manifest of a <em>base APK</em>. When adding new features you
+     * need to consider whether they should be supported by split APKs and child
+     * packages.
+     *
+     * @param res The resources from which to resolve values
+     * @param parser The manifest parser
+     * @param flags Flags how to parse
+     * @param outError Human readable error message
+     * @return Parsed package or null on error.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
      */
     private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags,
             String[] outError) throws XmlPullParserException, IOException {
-        final boolean trustedOverlay = (flags & PARSE_TRUSTED_OVERLAY) != 0;
-
-        AttributeSet attrs = parser;
-
-        mParseInstrumentationArgs = null;
-        mParseActivityArgs = null;
-        mParseServiceArgs = null;
-        mParseProviderArgs = null;
-
-        final String pkgName;
         final String splitName;
+        final String pkgName;
+
         try {
-            Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs, flags);
+            Pair<String, String> packageSplit = parsePackageSplitNames(parser, parser);
             pkgName = packageSplit.first;
             splitName = packageSplit.second;
+
+            if (!TextUtils.isEmpty(splitName)) {
+                outError[0] = "Expected base APK, but found split " + splitName;
+                mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
+                return null;
+            }
         } catch (PackageParserException e) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
             return null;
         }
 
-        int type;
-
-        if (!TextUtils.isEmpty(splitName)) {
-            outError[0] = "Expected base APK, but found split " + splitName;
-            mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
-            return null;
-        }
-
         final Package pkg = new Package(pkgName);
-        boolean foundApp = false;
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifest);
+
         pkg.mVersionCode = pkg.applicationInfo.versionCode = sa.getInteger(
                 com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
         pkg.baseRevisionCode = sa.getInteger(
@@ -1440,11 +1572,53 @@
         if (pkg.mVersionName != null) {
             pkg.mVersionName = pkg.mVersionName.intern();
         }
+
+        pkg.coreApp = parser.getAttributeBooleanValue(null, "coreApp", false);
+
+        sa.recycle();
+
+        return parseBaseApkCommon(pkg, null, res, parser, flags, outError);
+    }
+
+    /**
+     * This is the common parsing routing for handling parent and child
+     * packages in a base APK. The difference between parent and child
+     * parsing is that some targs are not supported by child packages as
+     * well as some manifest attributes are ignored. The implementation
+     * assumes the calling code already handled the manifest tag if needed
+     * (this applies to the parent only).
+     *
+     * @param pkg The package which to populate
+     * @param acceptedTags Which tags to handle, null to handle all
+     * @param res Resources against which to resolve values
+     * @param parser Parser of the manifest
+     * @param flags Flags about how to parse
+     * @param outError Human readable error if parsing fails
+     * @return The package if parsing succeeded or null.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     */
+    private Package parseBaseApkCommon(Package pkg, Set<String> acceptedTags, Resources res,
+            XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException,
+            IOException {
+        final boolean trustedOverlay = (flags & PARSE_TRUSTED_OVERLAY) != 0;
+        mParseInstrumentationArgs = null;
+        mParseActivityArgs = null;
+        mParseServiceArgs = null;
+        mParseProviderArgs = null;
+
+        int type;
+        boolean foundApp = false;
+
+        TypedArray sa = res.obtainAttributes(parser,
+                com.android.internal.R.styleable.AndroidManifest);
+
         String str = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
         if (str != null && str.length() > 0) {
             String nameError = validateName(str, true, false);
-            if (nameError != null && !"android".equals(pkgName)) {
+            if (nameError != null && !"android".equals(pkg.packageName)) {
                 outError[0] = "<manifest> specifies bad sharedUserId name \""
                     + str + "\": " + nameError;
                 mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
@@ -1460,9 +1634,6 @@
                 PARSE_DEFAULT_INSTALL_LOCATION);
         pkg.applicationInfo.installLocation = pkg.installLocation;
 
-        pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false);
-
-        sa.recycle();
 
         /* Set the global "forward lock" flag */
         if ((flags & PARSE_FORWARD_LOCK) != 0) {
@@ -1494,7 +1665,16 @@
             }
 
             String tagName = parser.getName();
-            if (tagName.equals("application")) {
+
+            if (acceptedTags != null && !acceptedTags.contains(tagName)) {
+                Slog.w(TAG, "Skipping unsupported element under <manifest>: "
+                        + tagName + " at " + mArchiveSourcePath + " "
+                        + parser.getPositionDescription());
+                XmlUtils.skipCurrentTag(parser);
+                continue;
+            }
+
+            if (tagName.equals(TAG_APPLICATION)) {
                 if (foundApp) {
                     if (RIGID_PARSER) {
                         outError[0] = "<manifest> has more than one <application>";
@@ -1508,13 +1688,13 @@
                 }
 
                 foundApp = true;
-                if (!parseBaseApplication(pkg, res, parser, attrs, flags, outError)) {
+                if (!parseBaseApplication(pkg, res, parser, flags, outError)) {
                     return null;
                 }
-            } else if (tagName.equals("overlay")) {
+            } else if (tagName.equals(TAG_OVERLAY)) {
                 pkg.mTrustedOverlay = trustedOverlay;
 
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestResourceOverlay);
                 pkg.mOverlayTarget = sa.getString(
                         com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
@@ -1536,34 +1716,34 @@
                 }
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("key-sets")) {
-                if (!parseKeySets(pkg, res, parser, attrs, outError)) {
+            } else if (tagName.equals(TAG_KEY_SETS)) {
+                if (!parseKeySets(pkg, res, parser, outError)) {
                     return null;
                 }
-            } else if (tagName.equals("permission-group")) {
-                if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
+            } else if (tagName.equals(TAG_PERMISSION_GROUP)) {
+                if (parsePermissionGroup(pkg, flags, res, parser, outError) == null) {
                     return null;
                 }
-            } else if (tagName.equals("permission")) {
-                if (parsePermission(pkg, res, parser, attrs, outError) == null) {
+            } else if (tagName.equals(TAG_PERMISSION)) {
+                if (parsePermission(pkg, res, parser, outError) == null) {
                     return null;
                 }
-            } else if (tagName.equals("permission-tree")) {
-                if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
+            } else if (tagName.equals(TAG_PERMISSION_TREE)) {
+                if (parsePermissionTree(pkg, res, parser, outError) == null) {
                     return null;
                 }
-            } else if (tagName.equals("uses-permission")) {
-                if (!parseUsesPermission(pkg, res, parser, attrs)) {
+            } else if (tagName.equals(TAG_USES_PERMISSION)) {
+                if (!parseUsesPermission(pkg, res, parser)) {
                     return null;
                 }
-            } else if (tagName.equals("uses-permission-sdk-m")
-                    || tagName.equals("uses-permission-sdk-23")) {
-                if (!parseUsesPermission(pkg, res, parser, attrs)) {
+            } else if (tagName.equals(TAG_USES_PERMISSION_SDK_M)
+                    || tagName.equals(TAG_USES_PERMISSION_SDK_23)) {
+                if (!parseUsesPermission(pkg, res, parser)) {
                     return null;
                 }
-            } else if (tagName.equals("uses-configuration")) {
+            } else if (tagName.equals(TAG_USES_CONFIGURATION)) {
                 ConfigurationInfo cPref = new ConfigurationInfo();
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestUsesConfiguration);
                 cPref.reqTouchScreen = sa.getInt(
                         com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
@@ -1589,8 +1769,8 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("uses-feature")) {
-                FeatureInfo fi = parseUsesFeature(res, attrs);
+            } else if (tagName.equals(TAG_USES_FEATURE)) {
+                FeatureInfo fi = parseUsesFeature(res, parser);
                 pkg.reqFeatures = ArrayUtils.add(pkg.reqFeatures, fi);
 
                 if (fi.name == null) {
@@ -1601,7 +1781,7 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("feature-group")) {
+            } else if (tagName.equals(TAG_FEATURE_GROUP)) {
                 FeatureGroupInfo group = new FeatureGroupInfo();
                 ArrayList<FeatureInfo> features = null;
                 final int innerDepth = parser.getDepth();
@@ -1613,7 +1793,7 @@
 
                     final String innerTagName = parser.getName();
                     if (innerTagName.equals("uses-feature")) {
-                        FeatureInfo featureInfo = parseUsesFeature(res, attrs);
+                        FeatureInfo featureInfo = parseUsesFeature(res, parser);
                         // FeatureGroups are stricter and mandate that
                         // any <uses-feature> declared are mandatory.
                         featureInfo.flags |= FeatureInfo.FLAG_REQUIRED;
@@ -1632,9 +1812,9 @@
                 }
                 pkg.featureGroups = ArrayUtils.add(pkg.featureGroups, group);
 
-            } else if (tagName.equals("uses-sdk")) {
+            } else if (tagName.equals(TAG_USES_SDK)) {
                 if (SDK_VERSION > 0) {
-                    sa = res.obtainAttributes(attrs,
+                    sa = res.obtainAttributes(parser,
                             com.android.internal.R.styleable.AndroidManifestUsesSdk);
 
                     int minVers = 0;
@@ -1723,8 +1903,8 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("supports-screens")) {
-                sa = res.obtainAttributes(attrs,
+            } else if (tagName.equals(TAG_SUPPORT_SCREENS)) {
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestSupportsScreens);
 
                 pkg.applicationInfo.requiresSmallestWidthDp = sa.getInteger(
@@ -1762,8 +1942,8 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("protected-broadcast")) {
-                sa = res.obtainAttributes(attrs,
+            } else if (tagName.equals(TAG_PROTECTED_BROADCAST)) {
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestProtectedBroadcast);
 
                 // Note: don't allow this value to be a reference to a resource
@@ -1784,13 +1964,12 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("instrumentation")) {
-                if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
+            } else if (tagName.equals(TAG_INSTRUMENTATION)) {
+                if (parseInstrumentation(pkg, res, parser, outError) == null) {
                     return null;
                 }
-
-            } else if (tagName.equals("original-package")) {
-                sa = res.obtainAttributes(attrs,
+            } else if (tagName.equals(TAG_ORIGINAL_PACKAGE)) {
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestOriginalPackage);
 
                 String orig =sa.getNonConfigurationString(
@@ -1807,8 +1986,8 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("adopt-permissions")) {
-                sa = res.obtainAttributes(attrs,
+            } else if (tagName.equals(TAG_ADOPT_PERMISSIONS)) {
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestOriginalPackage);
 
                 String name = sa.getNonConfigurationString(
@@ -1825,24 +2004,29 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            } else if (tagName.equals("uses-gl-texture")) {
+            } else if (tagName.equals(TAG_USES_GL_TEXTURE)) {
                 // Just skip this tag
                 XmlUtils.skipCurrentTag(parser);
                 continue;
 
-            } else if (tagName.equals("compatible-screens")) {
+            } else if (tagName.equals(TAG_COMPATIBLE_SCREENS)) {
                 // Just skip this tag
                 XmlUtils.skipCurrentTag(parser);
                 continue;
-            } else if (tagName.equals("supports-input")) {
+            } else if (tagName.equals(TAG_SUPPORTS_INPUT)) {//
                 XmlUtils.skipCurrentTag(parser);
                 continue;
 
-            } else if (tagName.equals("eat-comment")) {
+            } else if (tagName.equals(TAG_EAT_COMMENT)) {
                 // Just skip this tag
                 XmlUtils.skipCurrentTag(parser);
                 continue;
 
+            } else if (tagName.equals(TAG_PACKAGE)) {
+                if (!parseBaseApkChild(pkg, res, parser, flags, outError)) {
+                    // If parsing a child failed the error is already set
+                    return null;
+                }
             } else if (RIGID_PARSER) {
                 outError[0] = "Bad element under <manifest>: "
                     + parser.getName();
@@ -1943,6 +2127,8 @@
         // that may change.
         fi.name = sa.getNonResourceString(
                 com.android.internal.R.styleable.AndroidManifestUsesFeature_name);
+        fi.version = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestUsesFeature_version, 0);
         if (fi.name == null) {
             fi.reqGlEsVersion = sa.getInt(
                         com.android.internal.R.styleable.AndroidManifestUsesFeature_glEsVersion,
@@ -1956,9 +2142,9 @@
         return fi;
     }
 
-    private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser,
-            AttributeSet attrs) throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+    private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser)
+            throws XmlPullParserException, IOException {
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestUsesPermission);
 
         // Note: don't allow this value to be a reference to a resource
@@ -2078,7 +2264,7 @@
     }
 
     private boolean parseKeySets(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, String[] outError)
+            XmlResourceParser parser, String[] outError)
             throws XmlPullParserException, IOException {
         // we've encountered the 'key-sets' tag
         // all the keys and keysets that we want must be defined here
@@ -2108,7 +2294,7 @@
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
                 }
-                final TypedArray sa = res.obtainAttributes(attrs,
+                final TypedArray sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestKeySet);
                 final String keysetName = sa.getNonResourceString(
                     com.android.internal.R.styleable.AndroidManifestKeySet_name);
@@ -2123,7 +2309,7 @@
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
                 }
-                final TypedArray sa = res.obtainAttributes(attrs,
+                final TypedArray sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestPublicKey);
                 final String publicKeyName = sa.getNonResourceString(
                         com.android.internal.R.styleable.AndroidManifestPublicKey_name);
@@ -2164,7 +2350,7 @@
                 sa.recycle();
                 XmlUtils.skipCurrentTag(parser);
             } else if (tagName.equals("upgrade-key-set")) {
-                final TypedArray sa = res.obtainAttributes(attrs,
+                final TypedArray sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestUpgradeKeySet);
                 String name = sa.getNonResourceString(
                         com.android.internal.R.styleable.AndroidManifestUpgradeKeySet_name);
@@ -2223,11 +2409,11 @@
     }
 
     private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
-            XmlPullParser parser, AttributeSet attrs, String[] outError)
-        throws XmlPullParserException, IOException {
+            XmlResourceParser parser, String[] outError)
+            throws XmlPullParserException, IOException {
         PermissionGroup perm = new PermissionGroup(owner);
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup);
 
         if (!parsePackageItemInfo(owner, perm.info, outError,
@@ -2255,7 +2441,7 @@
 
         sa.recycle();
 
-        if (!parseAllMetaData(res, parser, attrs, "<permission-group>", perm,
+        if (!parseAllMetaData(res, parser, "<permission-group>", perm,
                 outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -2267,11 +2453,11 @@
     }
 
     private Permission parsePermission(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, String[] outError)
+            XmlResourceParser parser, String[] outError)
         throws XmlPullParserException, IOException {
         Permission perm = new Permission(owner);
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestPermission);
 
         if (!parsePackageItemInfo(owner, perm.info, outError,
@@ -2325,8 +2511,7 @@
             }
         }
 
-        if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
-                outError)) {
+        if (!parseAllMetaData(res, parser, "<permission>", perm, outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
         }
@@ -2337,11 +2522,11 @@
     }
 
     private Permission parsePermissionTree(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, String[] outError)
+            XmlResourceParser parser, String[] outError)
         throws XmlPullParserException, IOException {
         Permission perm = new Permission(owner);
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestPermissionTree);
 
         if (!parsePackageItemInfo(owner, perm.info, outError,
@@ -2373,7 +2558,7 @@
         perm.info.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
         perm.tree = true;
 
-        if (!parseAllMetaData(res, parser, attrs, "<permission-tree>", perm,
+        if (!parseAllMetaData(res, parser, "<permission-tree>", perm,
                 outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -2385,9 +2570,9 @@
     }
 
     private Instrumentation parseInstrumentation(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, String[] outError)
-        throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+            XmlResourceParser parser, String[] outError)
+            throws XmlPullParserException, IOException {
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestInstrumentation);
 
         if (mParseInstrumentationArgs == null) {
@@ -2433,7 +2618,7 @@
             return null;
         }
 
-        if (!parseAllMetaData(res, parser, attrs, "<instrumentation>", a,
+        if (!parseAllMetaData(res, parser, "<instrumentation>", a,
                 outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -2452,12 +2637,12 @@
      * supported by split APKs.
      */
     private boolean parseBaseApplication(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError)
         throws XmlPullParserException, IOException {
         final ApplicationInfo ai = owner.applicationInfo;
         final String pkgName = owner.applicationInfo.packageName;
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestApplication);
 
         String name = sa.getNonConfigurationString(
@@ -2608,10 +2793,13 @@
             ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
         }
 
-        if (sa.getBoolean(
-                com.android.internal.R.styleable.AndroidManifestApplication_testOnly,
-                false)) {
-            ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
+        // The parent package controls installation, hence specify test only installs.
+        if (owner.parentPackage == null) {
+            if (sa.getBoolean(
+                    com.android.internal.R.styleable.AndroidManifestApplication_testOnly,
+                    false)) {
+                ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
+            }
         }
 
         if (sa.getBoolean(
@@ -2736,7 +2924,7 @@
 
             String tagName = parser.getName();
             if (tagName.equals("activity")) {
-                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
+                Activity a = parseActivity(owner, res, parser, flags, outError, false,
                         owner.baseHardwareAccelerated);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -2746,7 +2934,7 @@
                 owner.activities.add(a);
 
             } else if (tagName.equals("receiver")) {
-                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
+                Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2755,7 +2943,7 @@
                 owner.receivers.add(a);
 
             } else if (tagName.equals("service")) {
-                Service s = parseService(owner, res, parser, attrs, flags, outError);
+                Service s = parseService(owner, res, parser, flags, outError);
                 if (s == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2764,7 +2952,7 @@
                 owner.services.add(s);
 
             } else if (tagName.equals("provider")) {
-                Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
+                Provider p = parseProvider(owner, res, parser, flags, outError);
                 if (p == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2773,7 +2961,7 @@
                 owner.providers.add(p);
 
             } else if (tagName.equals("activity-alias")) {
-                Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError);
+                Activity a = parseActivityAlias(owner, res, parser, flags, outError);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2785,14 +2973,14 @@
                 // note: application meta-data is stored off to the side, so it can
                 // remain null in the primary copy (we like to avoid extra copies because
                 // it can be large)
-                if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
+                if ((owner.mAppMetaData = parseMetaData(res, parser, owner.mAppMetaData,
                         outError)) == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
                 }
 
             } else if (tagName.equals("library")) {
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestLibrary);
 
                 // Note: don't allow this value to be a reference to a resource
@@ -2812,7 +3000,7 @@
                 XmlUtils.skipCurrentTag(parser);
 
             } else if (tagName.equals("uses-library")) {
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestUsesLibrary);
 
                 // Note: don't allow this value to be a reference to a resource
@@ -2913,10 +3101,10 @@
      * of doing, so many valid features of a base APK have been carefully
      * omitted here.
      */
-    private boolean parseSplitApplication(Package owner, Resources res, XmlPullParser parser,
-            AttributeSet attrs, int flags, int splitIndex, String[] outError)
+    private boolean parseSplitApplication(Package owner, Resources res, XmlResourceParser parser,
+            int flags, int splitIndex, String[] outError)
             throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestApplication);
 
         if (sa.getBoolean(
@@ -2934,7 +3122,7 @@
 
             String tagName = parser.getName();
             if (tagName.equals("activity")) {
-                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
+                Activity a = parseActivity(owner, res, parser, flags, outError, false,
                         owner.baseHardwareAccelerated);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -2944,7 +3132,7 @@
                 owner.activities.add(a);
 
             } else if (tagName.equals("receiver")) {
-                Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
+                Activity a = parseActivity(owner, res, parser, flags, outError, true, false);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2953,7 +3141,7 @@
                 owner.receivers.add(a);
 
             } else if (tagName.equals("service")) {
-                Service s = parseService(owner, res, parser, attrs, flags, outError);
+                Service s = parseService(owner, res, parser, flags, outError);
                 if (s == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2962,7 +3150,7 @@
                 owner.services.add(s);
 
             } else if (tagName.equals("provider")) {
-                Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
+                Provider p = parseProvider(owner, res, parser, flags, outError);
                 if (p == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2971,7 +3159,7 @@
                 owner.providers.add(p);
 
             } else if (tagName.equals("activity-alias")) {
-                Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError);
+                Activity a = parseActivityAlias(owner, res, parser, flags, outError);
                 if (a == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
@@ -2983,14 +3171,14 @@
                 // note: application meta-data is stored off to the side, so it can
                 // remain null in the primary copy (we like to avoid extra copies because
                 // it can be large)
-                if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
+                if ((owner.mAppMetaData = parseMetaData(res, parser, owner.mAppMetaData,
                         outError)) == null) {
                     mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                     return false;
                 }
 
             } else if (tagName.equals("uses-library")) {
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestUsesLibrary);
 
                 // Note: don't allow this value to be a reference to a resource
@@ -3086,10 +3274,10 @@
     }
 
     private Activity parseActivity(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError,
+            XmlResourceParser parser, int flags, String[] outError,
             boolean receiver, boolean hardwareAccelerated)
             throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs, R.styleable.AndroidManifestActivity);
+        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestActivity);
 
         if (mParseActivityArgs == null) {
             mParseActivityArgs = new ParseComponentArgs(owner, outError,
@@ -3261,9 +3449,8 @@
                 }
             } else if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.N) {
                 a.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
-            } else if (a.info.screenOrientation == SCREEN_ORIENTATION_UNSPECIFIED
-                    && (a.info.flags & FLAG_IMMERSIVE) == 0) {
-                a.info.resizeMode = RESIZE_MODE_CROP_WINDOWS;
+            } else if (!a.info.isFixedOrientation() && (a.info.flags & FLAG_IMMERSIVE) == 0) {
+                a.info.resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
             }
 
             if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysFocusable, false)) {
@@ -3327,7 +3514,7 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
-                if (!parseIntent(res, parser, attrs, true, true, intent, outError)) {
+                if (!parseIntent(res, parser, true, true, intent, outError)) {
                     return null;
                 }
                 if (intent.countActions() == 0) {
@@ -3339,7 +3526,7 @@
                 }
             } else if (!receiver && parser.getName().equals("preferred")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
-                if (!parseIntent(res, parser, attrs, false, false, intent, outError)) {
+                if (!parseIntent(res, parser, false, false, intent, outError)) {
                     return null;
                 }
                 if (intent.countActions() == 0) {
@@ -3353,12 +3540,12 @@
                     owner.preferredActivityFilters.add(intent);
                 }
             } else if (parser.getName().equals("meta-data")) {
-                if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData,
+                if ((a.metaData = parseMetaData(res, parser, a.metaData,
                         outError)) == null) {
                     return null;
                 }
             } else if (!receiver && parser.getName().equals("layout")) {
-                parseLayout(res, attrs, a);
+                parseLayout(res, parser, a);
             } else {
                 if (!RIGID_PARSER) {
                     Slog.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
@@ -3432,9 +3619,9 @@
     }
 
     private Activity parseActivityAlias(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError)
             throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestActivityAlias);
 
         String targetActivity = sa.getNonConfigurationString(
@@ -3565,7 +3752,7 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ActivityIntentInfo intent = new ActivityIntentInfo(a);
-                if (!parseIntent(res, parser, attrs, true, true, intent, outError)) {
+                if (!parseIntent(res, parser, true, true, intent, outError)) {
                     return null;
                 }
                 if (intent.countActions() == 0) {
@@ -3576,7 +3763,7 @@
                     a.intents.add(intent);
                 }
             } else if (parser.getName().equals("meta-data")) {
-                if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
+                if ((a.metaData=parseMetaData(res, parser, a.metaData,
                         outError)) == null) {
                     return null;
                 }
@@ -3602,9 +3789,9 @@
     }
 
     private Provider parseProvider(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError)
             throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestProvider);
 
         if (mParseProviderArgs == null) {
@@ -3731,7 +3918,7 @@
         }
         p.info.authority = cpname.intern();
 
-        if (!parseProviderTags(res, parser, attrs, p, outError)) {
+        if (!parseProviderTags(res, parser, p, outError)) {
             return null;
         }
 
@@ -3739,8 +3926,7 @@
     }
 
     private boolean parseProviderTags(Resources res,
-            XmlPullParser parser, AttributeSet attrs,
-            Provider outInfo, String[] outError)
+            XmlResourceParser parser, Provider outInfo, String[] outError)
             throws XmlPullParserException, IOException {
         int outerDepth = parser.getDepth();
         int type;
@@ -3753,19 +3939,19 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ProviderIntentInfo intent = new ProviderIntentInfo(outInfo);
-                if (!parseIntent(res, parser, attrs, true, false, intent, outError)) {
+                if (!parseIntent(res, parser, true, false, intent, outError)) {
                     return false;
                 }
                 outInfo.intents.add(intent);
 
             } else if (parser.getName().equals("meta-data")) {
-                if ((outInfo.metaData=parseMetaData(res, parser, attrs,
+                if ((outInfo.metaData=parseMetaData(res, parser,
                         outInfo.metaData, outError)) == null) {
                     return false;
                 }
 
             } else if (parser.getName().equals("grant-uri-permission")) {
-                TypedArray sa = res.obtainAttributes(attrs,
+                TypedArray sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestGrantUriPermission);
 
                 PatternMatcher pa = null;
@@ -3817,7 +4003,7 @@
                 XmlUtils.skipCurrentTag(parser);
 
             } else if (parser.getName().equals("path-permission")) {
-                TypedArray sa = res.obtainAttributes(attrs,
+                TypedArray sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestPathPermission);
 
                 PathPermission pa = null;
@@ -3922,9 +4108,9 @@
     }
 
     private Service parseService(Package owner, Resources res,
-            XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
+            XmlResourceParser parser, int flags, String[] outError)
             throws XmlPullParserException, IOException {
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestService);
 
         if (mParseServiceArgs == null) {
@@ -4025,13 +4211,13 @@
 
             if (parser.getName().equals("intent-filter")) {
                 ServiceIntentInfo intent = new ServiceIntentInfo(s);
-                if (!parseIntent(res, parser, attrs, true, false, intent, outError)) {
+                if (!parseIntent(res, parser, true, false, intent, outError)) {
                     return null;
                 }
 
                 s.intents.add(intent);
             } else if (parser.getName().equals("meta-data")) {
-                if ((s.metaData=parseMetaData(res, parser, attrs, s.metaData,
+                if ((s.metaData=parseMetaData(res, parser, s.metaData,
                         outError)) == null) {
                     return null;
                 }
@@ -4056,10 +4242,8 @@
         return s;
     }
 
-    private boolean parseAllMetaData(Resources res,
-            XmlPullParser parser, AttributeSet attrs, String tag,
-            Component<?> outInfo, String[] outError)
-            throws XmlPullParserException, IOException {
+    private boolean parseAllMetaData(Resources res, XmlResourceParser parser, String tag,
+            Component<?> outInfo, String[] outError) throws XmlPullParserException, IOException {
         int outerDepth = parser.getDepth();
         int type;
         while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -4070,7 +4254,7 @@
             }
 
             if (parser.getName().equals("meta-data")) {
-                if ((outInfo.metaData=parseMetaData(res, parser, attrs,
+                if ((outInfo.metaData=parseMetaData(res, parser,
                         outInfo.metaData, outError)) == null) {
                     return false;
                 }
@@ -4091,11 +4275,10 @@
     }
 
     private Bundle parseMetaData(Resources res,
-            XmlPullParser parser, AttributeSet attrs,
-            Bundle data, String[] outError)
+            XmlResourceParser parser, Bundle data, String[] outError)
             throws XmlPullParserException, IOException {
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestMetaData);
 
         if (data == null) {
@@ -4234,11 +4417,11 @@
     private static final String ANDROID_RESOURCES
             = "http://schemas.android.com/apk/res/android";
 
-    private boolean parseIntent(Resources res, XmlPullParser parser, AttributeSet attrs,
+    private boolean parseIntent(Resources res, XmlResourceParser parser,
             boolean allowGlobs, boolean allowAutoVerify, IntentInfo outInfo, String[] outError)
             throws XmlPullParserException, IOException {
 
-        TypedArray sa = res.obtainAttributes(attrs,
+        TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestIntentFilter);
 
         int priority = sa.getInt(
@@ -4278,7 +4461,7 @@
 
             String nodeName = parser.getName();
             if (nodeName.equals("action")) {
-                String value = attrs.getAttributeValue(
+                String value = parser.getAttributeValue(
                         ANDROID_RESOURCES, "name");
                 if (value == null || value == "") {
                     outError[0] = "No value supplied for <android:name>";
@@ -4288,7 +4471,7 @@
 
                 outInfo.addAction(value);
             } else if (nodeName.equals("category")) {
-                String value = attrs.getAttributeValue(
+                String value = parser.getAttributeValue(
                         ANDROID_RESOURCES, "name");
                 if (value == null || value == "") {
                     outError[0] = "No value supplied for <android:name>";
@@ -4299,7 +4482,7 @@
                 outInfo.addCategory(value);
 
             } else if (nodeName.equals("data")) {
-                sa = res.obtainAttributes(attrs,
+                sa = res.obtainAttributes(parser,
                         com.android.internal.R.styleable.AndroidManifestData);
 
                 String str = sa.getNonConfigurationString(
@@ -4464,6 +4647,9 @@
 
         public ArrayList<String> protectedBroadcasts;
 
+        public Package parentPackage;
+        public ArrayList<Package> childPackages;
+
         public ArrayList<String> libraryNames = null;
         public ArrayList<String> usesLibraries = null;
         public ArrayList<String> usesOptionalLibraries = null;
@@ -4555,6 +4741,12 @@
          * and prods fields out of {@code this.applicationInfo}.
          */
         public String cpuAbiOverride;
+        /**
+         * The install time abi override to choose 32bit abi's when multiple abi's
+         * are present. This is only meaningfull for multiarch applications.
+         * The use32bitAbi attribute is ignored if cpuAbiOverride is also set.
+         */
+        public boolean use32bitAbi;
 
         public Package(String packageName) {
             this.packageName = packageName;
@@ -4562,6 +4754,141 @@
             applicationInfo.uid = -1;
         }
 
+        public void setApplicationVolumeUuid(String volumeUuid) {
+            this.applicationInfo.volumeUuid = volumeUuid;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.volumeUuid = volumeUuid;
+                }
+            }
+        }
+
+        public void setApplicationInfoCodePath(String codePath) {
+            this.applicationInfo.setCodePath(codePath);
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.setCodePath(codePath);
+                }
+            }
+        }
+
+        public void setApplicationInfoResourcePath(String resourcePath) {
+            this.applicationInfo.setResourcePath(resourcePath);
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.setResourcePath(resourcePath);
+                }
+            }
+        }
+
+        public void setApplicationInfoBaseResourcePath(String resourcePath) {
+            this.applicationInfo.setBaseResourcePath(resourcePath);
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.setBaseResourcePath(resourcePath);
+                }
+            }
+        }
+
+        public void setApplicationInfoBaseCodePath(String baseCodePath) {
+            this.applicationInfo.setBaseCodePath(baseCodePath);
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.setBaseCodePath(baseCodePath);
+                }
+            }
+        }
+
+        public boolean hasChildPackage(String packageName) {
+            final int childCount = (childPackages != null) ? childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                if (childPackages.get(i).packageName.equals(packageName)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public void setApplicationInfoSplitCodePaths(String[] splitCodePaths) {
+            this.applicationInfo.setSplitCodePaths(splitCodePaths);
+            // Children have no splits
+        }
+
+        public void setApplicationInfoSplitResourcePaths(String[] resroucePaths) {
+            this.applicationInfo.setSplitResourcePaths(resroucePaths);
+            // Children have no splits
+        }
+
+        public void setSplitCodePaths(String[] codePaths) {
+            this.splitCodePaths = codePaths;
+        }
+
+        public void setCodePath(String codePath) {
+            this.codePath = codePath;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).codePath = codePath;
+                }
+            }
+        }
+
+        public void setBaseCodePath(String baseCodePath) {
+            this.baseCodePath = baseCodePath;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).baseCodePath = baseCodePath;
+                }
+            }
+        }
+
+        public void setSignatures(Signature[] signatures) {
+            this.mSignatures = signatures;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).mSignatures = signatures;
+                }
+            }
+        }
+
+        public void setVolumeUuid(String volumeUuid) {
+            this.volumeUuid = volumeUuid;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).volumeUuid = volumeUuid;
+                }
+            }
+        }
+
+        public void setApplicationInfoFlags(int mask, int flags) {
+            applicationInfo.flags = (applicationInfo.flags & ~mask) | (mask & flags);
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).applicationInfo.flags =
+                            (applicationInfo.flags & ~mask) | (mask & flags);
+                }
+            }
+        }
+
+        public void setUse32bitAbi(boolean use32bitAbi) {
+            this.use32bitAbi = use32bitAbi;
+            if (childPackages != null) {
+                final int packageCount = childPackages.size();
+                for (int i = 0; i < packageCount; i++) {
+                    childPackages.get(i).use32bitAbi = use32bitAbi;
+                }
+            }
+        }
+
         public List<String> getAllCodePaths() {
             ArrayList<String> paths = new ArrayList<>();
             paths.add(baseCodePath);
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 766868d..8724a96 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -847,6 +847,9 @@
          * to make forward progress from the partial results and avoid waiting for the completed
          * result.</p>
          *
+         * <p>For a particular request, {@link #onCaptureProgressed} may happen before or after
+         * {@link #onCaptureStarted}.</p>
+         *
          * <p>Each request will generate at least {@code 1} partial results, and at most
          * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT} partial results.</p>
          *
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index e88bc26..9870e7b 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -20,7 +20,12 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.BackupUtils;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.util.Objects;
 
 /**
@@ -30,6 +35,11 @@
  * @hide
  */
 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
+    /**
+     * Current Version of the Backup Serializer.
+     */
+    private static final int BACKUP_VERSION = 1;
+
     public static final int CYCLE_NONE = -1;
     public static final long WARNING_DISABLED = -1;
     public static final long LIMIT_DISABLED = -1;
@@ -191,4 +201,41 @@
             return new NetworkPolicy[size];
         }
     };
+
+    public byte[] getBytesForBackup() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(baos);
+
+        out.writeInt(BACKUP_VERSION);
+        out.write(template.getBytesForBackup());
+        out.writeInt(cycleDay);
+        BackupUtils.writeString(out, cycleTimezone);
+        out.writeLong(warningBytes);
+        out.writeLong(limitBytes);
+        out.writeLong(lastWarningSnooze);
+        out.writeLong(lastLimitSnooze);
+        out.writeInt(metered ? 1 : 0);
+        out.writeInt(inferred ? 1 : 0);
+        return baos.toByteArray();
+    }
+
+    public static NetworkPolicy getNetworkPolicyFromBackup(DataInputStream in) throws IOException,
+            BackupUtils.BadVersionException {
+        int version = in.readInt();
+        if (version < 1 || version > BACKUP_VERSION) {
+            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
+        }
+
+        NetworkTemplate template = NetworkTemplate.getNetworkTemplateFromBackup(in);
+        int cycleDay = in.readInt();
+        String cycleTimeZone = BackupUtils.readString(in);
+        long warningBytes = in.readLong();
+        long limitBytes = in.readLong();
+        long lastWarningSnooze = in.readLong();
+        long lastLimitSnooze = in.readLong();
+        boolean metered = in.readInt() == 1;
+        boolean inferred = in.readInt() == 1;
+        return new NetworkPolicy(template, cycleDay, cycleTimeZone, warningBytes, limitBytes,
+                lastWarningSnooze, lastLimitSnooze, metered, inferred);
+    }
 }
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 3f36d65..b6fe68a 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -105,7 +105,8 @@
     /**
      * Broadcast action: the active scorer has been changed. Scorer apps may listen to this to
      * perform initialization once selected as the active scorer, or clean up unneeded resources
-     * if another scorer has been selected. Note that it is unnecessary to clear existing scores as
+     * if another scorer has been selected. This is an explicit broadcast only sent to the
+     * previous scorer and new scorer. Note that it is unnecessary to clear existing scores as
      * this is handled by the system.
      *
      * <p>The new scorer will be specified in {@link #EXTRA_NEW_SCORER}.
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index b7a411e..5761d66 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -28,15 +28,21 @@
 import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
 import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
 import static android.telephony.TelephonyManager.getNetworkClass;
+
 import static com.android.internal.util.ArrayUtils.contains;
 
 import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.BackupUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.Objects;
 
@@ -47,6 +53,10 @@
  * @hide
  */
 public class NetworkTemplate implements Parcelable {
+    /**
+     * Current Version of the Backup Serializer.
+     */
+    private static final int BACKUP_VERSION = 1;
 
     public static final int MATCH_MOBILE_ALL = 1;
     @Deprecated
@@ -443,4 +453,31 @@
             return new NetworkTemplate[size];
         }
     };
+
+    public byte[] getBytesForBackup() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(baos);
+
+        out.writeInt(BACKUP_VERSION);
+
+        out.writeInt(mMatchRule);
+        BackupUtils.writeString(out, mSubscriberId);
+        BackupUtils.writeString(out, mNetworkId);
+
+        return baos.toByteArray();
+    }
+
+    public static NetworkTemplate getNetworkTemplateFromBackup(DataInputStream in)
+            throws IOException, BackupUtils.BadVersionException {
+        int version = in.readInt();
+        if (version < 1 || version > BACKUP_VERSION) {
+            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
+        }
+
+        int matchRule = in.readInt();
+        String subscriberId = BackupUtils.readString(in);
+        String networkId = BackupUtils.readString(in);
+
+        return new NetworkTemplate(matchRule, subscriberId, networkId);
+    }
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index acd780d..6f911ce 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -414,7 +414,7 @@
             return false;
         }
         try {
-            return pm.hasSystemFeature(PackageManager.FEATURE_NFC);
+            return pm.hasSystemFeature(PackageManager.FEATURE_NFC, 0);
         } catch (RemoteException e) {
             Log.e(TAG, "Package manager query failed, assuming no NFC feature", e);
             return false;
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 23d05bd..b49288e 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -156,7 +156,7 @@
                 throw new UnsupportedOperationException();
             }
             try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION, 0)) {
                     Log.e(TAG, "This device does not support card emulation");
                     throw new UnsupportedOperationException();
                 }
diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
index d61ac02..42ccf20 100644
--- a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
+++ b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
@@ -77,7 +77,7 @@
                 throw new UnsupportedOperationException();
             }
             try {
-                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+                if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, 0)) {
                     Log.e(TAG, "This device does not support NFC-F card emulation");
                     throw new UnsupportedOperationException();
                 }
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index e841dfe..1085b1e 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -176,35 +176,37 @@
         return DIR_VENDOR_ROOT;
     }
 
-    /** {@hide} */
-    @Deprecated
-    public static File getSystemSecureDirectory() {
-        return getDataSystemDirectory();
-    }
-
-    /** {@hide} */
-    @Deprecated
-    public static File getSecureDataDirectory() {
-        return getDataDirectory();
-    }
-
     /**
-     * Return the system directory for a user. This is for use by system services to store
-     * files relating to the user. This directory will be automatically deleted when the user
-     * is removed.
+     * Return the system directory for a user. This is for use by system
+     * services to store files relating to the user. This directory will be
+     * automatically deleted when the user is removed.
      *
+     * @deprecated This directory is valid and still exists, but callers should
+     *             <em>strongly</em> consider switching to
+     *             {@link #getDataSystemCeDirectory(int)} which is protected
+     *             with user credentials or
+     *             {@link #getDataSystemDeDirectory(int)} which supports fast
+     *             user wipe.
      * @hide
      */
+    @Deprecated
     public static File getUserSystemDirectory(int userId) {
         return new File(new File(getDataSystemDirectory(), "users"), Integer.toString(userId));
     }
 
     /**
-     * Returns the config directory for a user. This is for use by system services to store files
-     * relating to the user which should be readable by any app running as that user.
+     * Returns the config directory for a user. This is for use by system
+     * services to store files relating to the user which should be readable by
+     * any app running as that user.
      *
+     * @deprecated This directory is valid and still exists, but callers should
+     *             <em>strongly</em> consider switching to
+     *             {@link #getDataMiscCeDirectory(int)} which is protected with
+     *             user credentials or {@link #getDataMiscDeDirectory(int)}
+     *             which supports fast user wipe.
      * @hide
      */
+    @Deprecated
     public static File getUserConfigDirectory(int userId) {
         return new File(new File(new File(
                 getDataDirectory(), "misc"), "user"), Integer.toString(userId));
@@ -232,13 +234,28 @@
     }
 
     /** {@hide} */
-    public static File getDataSystemCredentialEncryptedDirectory() {
-        return new File(getDataDirectory(), "system_ce");
+    public static File getDataSystemCeDirectory(int userId) {
+        return buildPath(getDataDirectory(), "system_ce", String.valueOf(userId));
     }
 
     /** {@hide} */
-    public static File getDataSystemCredentialEncryptedDirectory(int userId) {
-        return new File(getDataSystemCredentialEncryptedDirectory(), String.valueOf(userId));
+    public static File getDataSystemDeDirectory(int userId) {
+        return buildPath(getDataDirectory(), "system_de", String.valueOf(userId));
+    }
+
+    /** {@hide} */
+    public static File getDataMiscDirectory() {
+        return new File(getDataDirectory(), "misc");
+    }
+
+    /** {@hide} */
+    public static File getDataMiscCeDirectory(int userId) {
+        return buildPath(getDataDirectory(), "misc_ce", String.valueOf(userId));
+    }
+
+    /** {@hide} */
+    public static File getDataMiscDeDirectory(int userId) {
+        return buildPath(getDataDirectory(), "misc_de", String.valueOf(userId));
     }
 
     /** {@hide} */
@@ -252,57 +269,37 @@
     }
 
     /** {@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) {
+    public static File getDataUserCeDirectory(String volumeUuid) {
         return new File(getDataDirectory(volumeUuid), "user");
     }
 
     /** {@hide} */
-    public static File getDataUserCredentialEncryptedDirectory(String volumeUuid, int userId) {
-        return new File(getDataUserCredentialEncryptedDirectory(volumeUuid),
-                String.valueOf(userId));
+    public static File getDataUserCeDirectory(String volumeUuid, int userId) {
+        return new File(getDataUserCeDirectory(volumeUuid), String.valueOf(userId));
     }
 
     /** {@hide} */
-    public static File getDataUserCredentialEncryptedPackageDirectory(String volumeUuid, int userId,
+    public static File getDataUserCePackageDirectory(String volumeUuid, int userId,
             String packageName) {
         // TODO: keep consistent with installd
-        return new File(getDataUserCredentialEncryptedDirectory(volumeUuid, userId), packageName);
+        return new File(getDataUserCeDirectory(volumeUuid, userId), packageName);
     }
 
     /** {@hide} */
-    public static File getDataUserDeviceEncryptedDirectory(String volumeUuid) {
+    public static File getDataUserDeDirectory(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));
+    public static File getDataUserDeDirectory(String volumeUuid, int userId) {
+        return new File(getDataUserDeDirectory(volumeUuid), String.valueOf(userId));
     }
 
     /** {@hide} */
-    public static File getDataUserDeviceEncryptedPackageDirectory(String volumeUuid, int userId,
+    public static File getDataUserDePackageDirectory(String volumeUuid, int userId,
             String packageName) {
         // TODO: keep consistent with installd
-        return new File(getDataUserDeviceEncryptedDirectory(volumeUuid, userId), packageName);
+        return new File(getDataUserDeDirectory(volumeUuid, userId), packageName);
     }
 
     /**
@@ -342,7 +339,7 @@
      * <p>
      * Writing to this path requires the
      * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission,
-     * and starting in read access requires the
+     * and starting in {@link android.os.Build.VERSION_CODES#KITKAT}, read access requires the
      * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission,
      * which is automatically granted if you hold the write permission.
      * <p>
@@ -479,11 +476,6 @@
     public static String DIRECTORY_DOCUMENTS = "Documents";
 
     /**
-     * Standard directory in which user managed files are stored.
-     */
-    public static String DIRECTORY_HOME = "Home";
-
-    /**
      * List of standard storage directories.
      * <p>
      * Each of its values have its own constant:
@@ -498,7 +490,6 @@
      *   <li>{@link #DIRECTORY_DOWNLOADS}
      *   <li>{@link #DIRECTORY_DCIM}
      *   <li>{@link #DIRECTORY_DOCUMENTS}
-     *   <li>{@link #DIRECTORY_HOME}
      * </ul>
      * @hide
      */
@@ -512,8 +503,7 @@
             DIRECTORY_MOVIES,
             DIRECTORY_DOWNLOADS,
             DIRECTORY_DCIM,
-            DIRECTORY_DOCUMENTS,
-            DIRECTORY_HOME
+            DIRECTORY_DOCUMENTS
     };
 
     /**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index b51d2dfb..9984755 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -823,6 +823,16 @@
     }
 
     /**
+     * Returns whether the given uid belongs to an application.
+     * @param uid A kernel uid.
+     * @return Whether the uid corresponds to an application sandbox running in
+     *     a specific user.
+     */
+    public static boolean isApplicationUid(int uid) {
+        return UserHandle.isApp(uid);
+    }
+
+    /**
      * Returns whether the current process is in an isolated sandbox.
      * @hide
      */
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
new file mode 100644
index 0000000..80e6146
--- /dev/null
+++ b/core/java/android/os/UpdateEngine.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.annotation.SystemApi;
+import android.os.IUpdateEngine;
+import android.os.IUpdateEngineCallback;
+import android.os.RemoteException;
+
+import android.util.Log;
+
+/**
+ * UpdateEngine handles calls to the update engine which takes care of A/B OTA
+ * updates. It wraps up the update engine Binder APIs and exposes them as
+ * SystemApis, which will be called by system apps like GmsCore.
+ *
+ * The APIs defined in this class and UpdateEngineCallback class must be in
+ * sync with the ones in
+ * system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl and
+ * system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl.
+ *
+ * {@hide}
+ */
+@SystemApi
+public class UpdateEngine {
+    private static final String TAG = "UpdateEngine";
+
+    private static final String UPDATE_ENGINE_SERVICE = "android.os.UpdateEngineService";
+
+    /**
+     * Error code from the update engine. Values must agree with the ones in
+     * system/update_engine/common/error_code.h.
+     */
+    @SystemApi
+    public static final class ErrorCodeConstants {
+        public static final int SUCCESS = 0;
+        public static final int ERROR = 1;
+        public static final int FILESYSTEM_COPIER_ERROR = 4;
+        public static final int POST_INSTALL_RUNNER_ERROR = 5;
+        public static final int PAYLOAD_MISMATCHED_TYPE_ERROR = 6;
+        public static final int INSTALL_DEVICE_OPEN_ERROR = 7;
+        public static final int KERNEL_DEVICE_OPEN_ERROR = 8;
+        public static final int DOWNLOAD_TRANSFER_ERROR = 9;
+        public static final int PAYLOAD_HASH_MISMATCH_ERROR = 10;
+        public static final int PAYLOAD_SIZE_MISMATCH_ERROR = 11;
+        public static final int DOWNLOAD_PAYLOAD_VERIFICATION_ERROR = 12;
+    }
+
+    /**
+     * Update status code from the update engine. Values must agree with the
+     * ones in system/update_engine/client_library/include/update_engine/update_status.h.
+     */
+    @SystemApi
+    public static final class UpdateStatusConstants {
+        public static final int IDLE = 0;
+        public static final int CHECKING_FOR_UPDATE = 1;
+        public static final int UPDATE_AVAILABLE = 2;
+        public static final int DOWNLOADING = 3;
+        public static final int VERIFYING = 4;
+        public static final int FINALIZING = 5;
+        public static final int UPDATED_NEED_REBOOT = 6;
+        public static final int REPORTING_ERROR_EVENT = 7;
+        public static final int ATTEMPTING_ROLLBACK = 8;
+        public static final int DISABLED = 9;
+    }
+
+    private IUpdateEngine mUpdateEngine;
+
+    @SystemApi
+    public UpdateEngine() {
+        mUpdateEngine = IUpdateEngine.Stub.asInterface(
+                ServiceManager.getService(UPDATE_ENGINE_SERVICE));
+    }
+
+    @SystemApi
+    public boolean bind(final UpdateEngineCallback callback, final Handler handler) throws RemoteException {
+        IUpdateEngineCallback updateEngineCallback = new IUpdateEngineCallback.Stub() {
+            @Override
+            public void onStatusUpdate(final int status, final float percent) {
+                if (handler != null) {
+                    handler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            callback.onStatusUpdate(status, percent);
+                        }
+                    });
+                } else {
+                    callback.onStatusUpdate(status, percent);
+                }
+            }
+
+            @Override
+            public void onPayloadApplicationComplete(final int errorCode) {
+                if (handler != null) {
+                    handler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            callback.onPayloadApplicationComplete(errorCode);
+                        }
+                    });
+                } else {
+                    callback.onPayloadApplicationComplete(errorCode);
+                }
+            }
+        };
+
+        return mUpdateEngine.bind(updateEngineCallback);
+    }
+
+    @SystemApi
+    public boolean bind(final UpdateEngineCallback callback) throws RemoteException {
+        return bind(callback, null);
+    }
+
+    @SystemApi
+    public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) throws RemoteException {
+        mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
+    }
+
+    @SystemApi
+    public void cancel() throws RemoteException {
+        mUpdateEngine.cancel();
+    }
+
+    @SystemApi
+    public void suspend() throws RemoteException {
+        mUpdateEngine.suspend();
+    }
+
+    @SystemApi
+    public void resume() throws RemoteException {
+        mUpdateEngine.resume();
+    }
+}
diff --git a/core/java/android/os/UpdateEngineCallback.java b/core/java/android/os/UpdateEngineCallback.java
new file mode 100644
index 0000000..b3b856f
--- /dev/null
+++ b/core/java/android/os/UpdateEngineCallback.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.annotation.SystemApi;
+
+/**
+ * Callback function for UpdateEngine.
+ *
+ * The APIs defined in this class and UpdateEngine class must be in sync with
+ * the ones in
+ * system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl and
+ * system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl.
+ *
+ * {@hide}
+ */
+@SystemApi
+public abstract class UpdateEngineCallback {
+
+    @SystemApi
+    public abstract void onStatusUpdate(int status, float percent);
+
+    @SystemApi
+    public abstract void onPayloadApplicationComplete(int errorCode);
+}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 24666fe..b3f4453 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -130,6 +130,15 @@
     }
 
     /**
+     * Returns the user for a given uid.
+     * @param uid A uid for an application running in a particular user.
+     * @return A {@link UserHandle} for that user.
+     */
+    public static UserHandle getUserHandleForUid(int uid) {
+        return of(getUserId(uid));
+    }
+
+    /**
      * Returns the user id for a given uid.
      * @hide
      */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index dc0e249..69d564f 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1141,6 +1141,8 @@
         UserInfo user = null;
         try {
             user = mService.createUser(name, flags);
+            // TODO: Keep this in sync with
+            // UserManagerService.LocalService.createUserEvenWhenDisallowed
             if (user != null && !user.isAdmin()) {
                 mService.setUserRestriction(DISALLOW_SMS, true, user.id);
                 mService.setUserRestriction(DISALLOW_OUTGOING_CALLS, true, user.id);
diff --git a/core/java/android/os/UserManagerInternal.java b/core/java/android/os/UserManagerInternal.java
index 58a0269..d2ece8b 100644
--- a/core/java/android/os/UserManagerInternal.java
+++ b/core/java/android/os/UserManagerInternal.java
@@ -17,6 +17,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.UserInfo;
 import android.graphics.Bitmap;
 
 /**
@@ -106,4 +107,12 @@
      * non-ephemeral users left.
      */
     public abstract void removeAllUsers();
+
+    /**
+     * Same as UserManager.createUser(), but bypasses the check for DISALLOW_ADD_USER.
+     *
+     * <p>Called by the {@link com.android.server.devicepolicy.DevicePolicyManagerService} when
+     * createAndManageUser is called by the device owner.
+     */
+    public abstract UserInfo createUserEvenWhenDisallowed(String name, int flags);
 }
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index dd8eb5f..fc440d2 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1233,7 +1233,8 @@
             }
 
             @Override
-            public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException {
+            public void changeUserKey(int userId, int serialNumber,
+                    byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
@@ -1241,6 +1242,27 @@
                     _data.writeInt(userId);
                     _data.writeInt(serialNumber);
                     _data.writeByteArray(token);
+                    _data.writeByteArray(oldSecret);
+                    _data.writeByteArray(newSecret);
+                    mRemote.transact(Stub.TRANSACTION_changeUserKey, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public void unlockUserKey(int userId, int serialNumber,
+                    byte[] token, byte[] secret) throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(userId);
+                    _data.writeInt(serialNumber);
+                    _data.writeByteArray(token);
+                    _data.writeByteArray(secret);
                     mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
                     _reply.readException();
                 } finally {
@@ -1448,6 +1470,8 @@
 
         static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69;
 
+        static final int TRANSACTION_changeUserKey = IBinder.FIRST_CALL_TRANSACTION + 70;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -2026,12 +2050,24 @@
                     reply.writeNoException();
                     return true;
                 }
+                case TRANSACTION_changeUserKey: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int userId = data.readInt();
+                    int serialNumber = data.readInt();
+                    byte[] token = data.createByteArray();
+                    byte[] oldSecret = data.createByteArray();
+                    byte[] newSecret = data.createByteArray();
+                    changeUserKey(userId, serialNumber, token, oldSecret, newSecret);
+                    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);
+                    byte[] secret = data.createByteArray();
+                    unlockUserKey(userId, serialNumber, token, secret);
                     reply.writeNoException();
                     return true;
                 }
@@ -2383,8 +2419,11 @@
     public void createUserKey(int userId, int serialNumber, boolean ephemeral)
             throws RemoteException;
     public void destroyUserKey(int userId) throws RemoteException;
+    public void changeUserKey(int userId, int serialNumber,
+            byte[] token, byte[] oldSecret, byte[] newSecret) throws RemoteException;
 
-    public void unlockUserKey(int userId, int serialNumber, byte[] token) throws RemoteException;
+    public void unlockUserKey(int userId, int serialNumber,
+            byte[] token, byte[] secret) throws RemoteException;
     public void lockUserKey(int userId) throws RemoteException;
     public boolean isUserKeyUnlocked(int userId) throws RemoteException;
 
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index b82638a..97ee90d 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -865,7 +865,12 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * Gets the list of shared/external storage volumes available to the current user.
+     *
+     * <p>It always contains the primary storage volume, plus any additional external volume(s)
+     * available in the device, such as SD cards or attached USB drives.
+     */
     public @NonNull StorageVolume[] getVolumeList() {
         return getVolumeList(mContext.getUserId(), 0);
     }
@@ -914,7 +919,9 @@
         return paths;
     }
 
-    /** {@hide} */
+    /**
+     * Gets the primary shared/external storage volume available to the current user.
+     */
     public @NonNull StorageVolume getPrimaryVolume() {
         return getPrimaryVolume(getVolumeList());
     }
@@ -991,9 +998,9 @@
     }
 
     /** {@hide} */
-    public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
         try {
-            mMountService.unlockUserKey(userId, serialNumber, token);
+            mMountService.unlockUserKey(userId, serialNumber, token, secret);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index 1408202..d860c7d 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -16,11 +16,17 @@
 
 package android.os.storage;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.Intent;
 import android.net.TrafficStats;
+import android.net.Uri;
+import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
+import android.provider.DocumentsContract;
 
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
@@ -29,14 +35,47 @@
 import java.io.File;
 
 /**
- * Information about a storage volume that may be mounted. This is a legacy
- * specialization of {@link VolumeInfo} which describes the volume for a
- * specific user.
- * <p>
- * This class may be deprecated in the future.
+ * Information about a shared/external storage volume for a specific user.
  *
- * @hide
+ * <p>
+ * A device always has one (and one only) primary storage volume, but it could have extra volumes,
+ * like SD cards and USB drives. This object represents the logical view of a storage
+ * volume for a specific user: different users might have different views for the same physical
+ * volume (for example, if the volume is a built-in emulated storage).
+ *
+ * <p>
+ * The storage volume is not necessarily mounted, applications should use {@link #getState()} to
+ * verify its state.
+ *
+ * <p>
+ * Applications willing to read or write to this storage volume needs to get a permission from the
+ * user first, which can be achieved in the following ways:
+ *
+ * <ul>
+ * <li>To get access to standard directories (like the {@link Environment#DIRECTORY_PICTURES}), they
+ * can use the {@link #createAccessIntent(String)}. This is the recommend way, since it provides a
+ * simpler API and narrows the access to the given directory (and its descendants).
+ * <li>To get access to any directory (and its descendants), they can use the Storage Acess
+ * Framework APIs (such as {@link Intent#ACTION_OPEN_DOCUMENT} and
+ * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, although these APIs do not guarantee the user will
+ * select this specific volume.
+ * <li>To get read and write access to the primary storage volume, applications can declare the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} and
+ * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions respectively, with the
+ * latter including the former. This approach is discouraged, since users may be hesitant to grant
+ * broad access to all files contained on a storage device.
+ * </ul>
+ *
+ * <p>It can be obtained through {@link StorageManager#getVolumeList()} and
+ * {@link StorageManager#getPrimaryVolume()} and also as an extra in some broadcasts
+ * (see {@link #EXTRA_STORAGE_VOLUME}).
+ *
+ * <p>
+ * See {@link Environment#getExternalStorageDirectory()} for more info about shared/external
+ * storage semantics.
  */
+// NOTE: This is a legacy specialization of VolumeInfo which describes the volume for a specific
+// user, but is now part of the public API.
 public class StorageVolume implements Parcelable {
 
     private final String mId;
@@ -53,14 +92,36 @@
     private final String mFsUuid;
     private final String mState;
 
-    // StorageVolume extra for ACTION_MEDIA_REMOVED, ACTION_MEDIA_UNMOUNTED, ACTION_MEDIA_CHECKING,
-    // ACTION_MEDIA_NOFS, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_SHARED, ACTION_MEDIA_UNSHARED,
-    // ACTION_MEDIA_BAD_REMOVAL, ACTION_MEDIA_UNMOUNTABLE and ACTION_MEDIA_EJECT broadcasts.
-    public static final String EXTRA_STORAGE_VOLUME = "storage_volume";
+    /**
+     * Name of the {@link Parcelable} extra in the {@link Intent#ACTION_MEDIA_REMOVED},
+     * {@link Intent#ACTION_MEDIA_UNMOUNTED}, {@link Intent#ACTION_MEDIA_CHECKING},
+     * {@link Intent#ACTION_MEDIA_NOFS}, {@link Intent#ACTION_MEDIA_MOUNTED},
+     * {@link Intent#ACTION_MEDIA_SHARED}, {@link Intent#ACTION_MEDIA_BAD_REMOVAL},
+     * {@link Intent#ACTION_MEDIA_UNMOUNTABLE}, and {@link Intent#ACTION_MEDIA_EJECT} broadcast that
+     * contains a {@link StorageVolume}.
+     */
+    // Also sent on ACTION_MEDIA_UNSHARED, which is @hide
+    public static final String EXTRA_STORAGE_VOLUME = "android.os.storage.extra.STORAGE_VOLUME";
 
+    /**
+     * Name of the String extra used by {@link #createAccessIntent(String) createAccessIntent}.
+     *
+     * @hide
+     */
+    public static final String EXTRA_DIRECTORY_NAME = "android.os.storage.extra.DIRECTORY_NAME";
+
+    /**
+     * Name of the intent used by {@link #createAccessIntent(String) createAccessIntent}.
+     */
+    private static final String ACTION_OPEN_EXTERNAL_DIRECTORY =
+            "android.os.storage.action.OPEN_EXTERNAL_DIRECTORY";
+
+    /** {@hide} */
     public static final int STORAGE_ID_INVALID = 0x00000000;
+    /** {@hide} */
     public static final int STORAGE_ID_PRIMARY = 0x00010001;
 
+    /** {@hide} */
     public StorageVolume(String id, int storageId, File path, String description, boolean primary,
             boolean removable, boolean emulated, long mtpReserveSize, boolean allowMassStorage,
             long maxFileSize, UserHandle owner, String fsUuid, String state) {
@@ -95,6 +156,7 @@
         mState = in.readString();
     }
 
+    /** {@hide} */
     public String getId() {
         return mId;
     }
@@ -103,17 +165,19 @@
      * Returns the mount path for the volume.
      *
      * @return the mount path
+     * @hide
      */
     public String getPath() {
         return mPath.toString();
     }
 
+    /** {@hide} */
     public File getPathFile() {
         return mPath;
     }
 
     /**
-     * Returns a user visible description of the volume.
+     * Returns a user-visible description of the volume.
      *
      * @return the volume description
      */
@@ -121,6 +185,10 @@
         return mDescription;
     }
 
+    /**
+     * Returns true if the volume is the primary shared/external storage, which is the volume
+     * backed by {@link Environment#getExternalStorageDirectory()}.
+     */
     public boolean isPrimary() {
         return mPrimary;
     }
@@ -148,6 +216,7 @@
      * this is also used for the storage_id column in the media provider.
      *
      * @return MTP storage ID
+     * @hide
      */
     public int getStorageId() {
         return mStorageId;
@@ -164,6 +233,7 @@
      * too close to full.
      *
      * @return MTP reserve space
+     * @hide
      */
     public int getMtpReserveSpace() {
         return (int) (mMtpReserveSize / TrafficStats.MB_IN_BYTES);
@@ -173,6 +243,7 @@
      * Returns true if this volume can be shared via USB mass storage.
      *
      * @return whether mass storage is allowed
+     * @hide
      */
     public boolean allowMassStorage() {
         return mAllowMassStorage;
@@ -182,22 +253,28 @@
      * Returns maximum file size for the volume, or zero if it is unbounded.
      *
      * @return maximum file size
+     * @hide
      */
     public long getMaxFileSize() {
         return mMaxFileSize;
     }
 
+    /** {@hide} */
     public UserHandle getOwner() {
         return mOwner;
     }
 
-    public String getUuid() {
+    /**
+     * Gets the volume UUID, if any.
+     */
+    public @Nullable String getUuid() {
         return mFsUuid;
     }
 
     /**
      * Parse and return volume UUID as FAT volume ID, or return -1 if unable to
      * parse or UUID is unknown.
+     * @hide
      */
     public int getFatVolumeId() {
         if (mFsUuid == null || mFsUuid.length() != 9) {
@@ -210,14 +287,57 @@
         }
     }
 
+    /** {@hide} */
     public String getUserLabel() {
         return mDescription;
     }
 
+    /**
+     * Returns the current state of the volume.
+     *
+     * @return one of {@link Environment#MEDIA_UNKNOWN}, {@link Environment#MEDIA_REMOVED},
+     *         {@link Environment#MEDIA_UNMOUNTED}, {@link Environment#MEDIA_CHECKING},
+     *         {@link Environment#MEDIA_NOFS}, {@link Environment#MEDIA_MOUNTED},
+     *         {@link Environment#MEDIA_MOUNTED_READ_ONLY}, {@link Environment#MEDIA_SHARED},
+     *         {@link Environment#MEDIA_BAD_REMOVAL}, or {@link Environment#MEDIA_UNMOUNTABLE}.
+     */
     public String getState() {
         return mState;
     }
 
+    /**
+     * Builds an intent to give access to a standard storage directory after obtaining the user's
+     * approval.
+     * <p>
+     * When invoked, the system will ask the user to grant access to the requested directory (and
+     * its descendants). The result of the request will be returned to the activity through the
+     * {@code onActivityResult} method.
+     * <p>
+     * To gain access to descendants (child, grandchild, etc) documents, use
+     * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)}, or
+     * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI.
+     *
+     * <b>If your application only needs to store internal data, consider using
+     * {@link Context#getExternalFilesDirs(String) Context.getExternalFilesDirs},
+     * {@link Context#getExternalCacheDirs()}, or
+     * {@link Context#getExternalMediaDirs()}, which require no permissions to read or write.
+     *
+     * @param directoryName must be one of
+     * {@link Environment#DIRECTORY_MUSIC}, {@link Environment#DIRECTORY_PODCASTS},
+     * {@link Environment#DIRECTORY_RINGTONES}, {@link Environment#DIRECTORY_ALARMS},
+     * {@link Environment#DIRECTORY_NOTIFICATIONS}, {@link Environment#DIRECTORY_PICTURES},
+     * {@link Environment#DIRECTORY_MOVIES}, {@link Environment#DIRECTORY_DOWNLOADS},
+     * {@link Environment#DIRECTORY_DCIM}, or {@link Environment#DIRECTORY_DOCUMENTS}
+     *
+     * @see DocumentsContract
+     */
+    public Intent createAccessIntent(@NonNull String directoryName) {
+        final Intent intent = new Intent(ACTION_OPEN_EXTERNAL_DIRECTORY);
+        intent.putExtra(EXTRA_STORAGE_VOLUME, this);
+        intent.putExtra(EXTRA_DIRECTORY_NAME, directoryName);
+        return intent;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof StorageVolume && mPath != null) {
@@ -234,11 +354,23 @@
 
     @Override
     public String toString() {
+        final StringBuilder buffer = new StringBuilder("StorageVolume: ").append(mDescription);
+        if (mFsUuid != null) {
+            buffer.append(" (").append(mFsUuid).append(")");
+        }
+        return buffer.toString();
+    }
+
+    /** {@hide} */
+    // TODO(b/26742218): find out where toString() is called internally and replace these calls by
+    // dump().
+    public String dump() {
         final CharArrayWriter writer = new CharArrayWriter();
         dump(new IndentingPrintWriter(writer, "    ", 80));
         return writer.toString();
     }
 
+    /** {@hide} */
     public void dump(IndentingPrintWriter pw) {
         pw.println("StorageVolume:");
         pw.increaseIndent();
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index ea54f92..4d3bea4 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -223,4 +223,98 @@
         return res != null && res.getBoolean(RES_CAN_BLOCK_NUMBERS, false);
     }
 
+    /**
+     * <p>
+     * The contract between the blockednumber provider and the system.
+     * </p>
+     * <p>This is a wrapper over {@link BlockedNumberContract} that also manages the blocking
+     * behavior when the user contacts emergency services. See
+     * {@link #notifyEmergencyContact(Context)} for details. All methods are protected by
+     * {@link android.Manifest.permission#READ_BLOCKED_NUMBERS} and
+     * {@link android.Manifest.permission#WRITE_BLOCKED_NUMBERS} appropriately which ensure that
+     * only system can access the methods defined here.
+     * </p>
+     * @hide
+     */
+    public static class SystemContract {
+        /**
+         * A protected broadcast intent action for letting components with
+         * {@link android.Manifest.permission#READ_BLOCKED_NUMBERS} know that the block suppressal
+         * status as returned by {@link #getBlockSuppressalStatus(Context)} has been updated.
+         */
+        public static final String ACTION_BLOCK_SUPPRESSAL_STATE_CHANGED =
+                "android.provider.action.BLOCK_SUPPRESSAL_STATE_CHANGED";
+
+        public static final String METHOD_NOTIFY_EMERGENCY_CONTACT = "notify_emergency_contact";
+
+        public static final String METHOD_END_BLOCK_SUPPRESSAL = "end_block_suppressal";
+
+        public static final String METHOD_SHOULD_SYSTEM_BLOCK_NUMBER = "should_system_block_number";
+
+        public static final String METHOD_GET_BLOCK_SUPPRESSAL_STATUS =
+                "get_block_suppresal_status";
+
+        public static final String RES_IS_BLOCKING_SUPPRESSED = "blocking_suppressed";
+
+        public static final String RES_BLOCKING_SUPPRESSED_UNTIL_TIMESTAMP =
+                "blocking_suppressed_until_timestamp";
+
+        /**
+         * Notifies the provider that emergency services were contacted by the user.
+         * <p> This results in {@link #shouldSystemBlockNumber} returning {@code false} independent
+         * of the contents of the provider for a duration defined by
+         * {@link android.telephony.CarrierConfigManager#KEY_DURATION_BLOCKING_DISABLED_AFTER_EMERGENCY_INT}
+         * the provider unless {@link #endBlockSuppressal(Context)} is called.
+         */
+        public static void notifyEmergencyContact(Context context) {
+            context.getContentResolver().call(
+                    AUTHORITY_URI, METHOD_NOTIFY_EMERGENCY_CONTACT, null, null);
+        }
+
+        /**
+         * Notifies the provider to disable suppressing blocking. If emergency services were not
+         * contacted recently at all, calling this method is a no-op.
+         */
+        public static void endBlockSuppressal(Context context) {
+            context.getContentResolver().call(
+                    AUTHORITY_URI, METHOD_END_BLOCK_SUPPRESSAL, null, null);
+        }
+
+        /**
+         * Returns {@code true} if {@code phoneNumber} is blocked taking
+         * {@link #notifyEmergencyContact(Context)} into consideration. If emergency services have
+         * not been contacted recently, this method is equivalent to
+         * {@link #isBlocked(Context, String)}.
+         */
+        public static boolean shouldSystemBlockNumber(Context context, String phoneNumber) {
+            final Bundle res = context.getContentResolver().call(
+                    AUTHORITY_URI, METHOD_SHOULD_SYSTEM_BLOCK_NUMBER, phoneNumber, null);
+            return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+        }
+
+        public static BlockSuppressalStatus getBlockSuppressalStatus(Context context) {
+            final Bundle res = context.getContentResolver().call(
+                    AUTHORITY_URI, METHOD_GET_BLOCK_SUPPRESSAL_STATUS, null, null);
+            return new BlockSuppressalStatus(res.getBoolean(RES_IS_BLOCKING_SUPPRESSED, false),
+                    res.getLong(RES_BLOCKING_SUPPRESSED_UNTIL_TIMESTAMP, 0));
+        }
+
+        /**
+         * Represents the current status of {@link #shouldSystemBlockNumber(Context, String)}. If
+         * emergency services have been contacted recently, {@link #isSuppressed} is {@code true},
+         *  and blocking is disabled until the timestamp {@link #untilTimestampMillis}.
+         */
+        public static class BlockSuppressalStatus {
+            public final boolean isSuppressed;
+            /**
+             * Timestamp in milliseconds from epoch.
+             */
+            public final long untilTimestampMillis;
+
+            BlockSuppressalStatus(boolean isSuppressed, long untilTimestampMillis) {
+                this.isSuppressed = isSuppressed;
+                this.untilTimestampMillis = untilTimestampMillis;
+            }
+        }
+    }
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index dfdd36d..904b393 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -4982,6 +4982,17 @@
      */
     protected interface PhoneLookupColumns {
         /**
+         *  The ID of the data row.
+         *  <P>Type: INTEGER</P>
+         */
+        public static final String DATA_ID = "data_id";
+        /**
+         * A reference to the {@link ContactsContract.Contacts#_ID} that this
+         * data belongs to.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String CONTACT_ID = "contact_id";
+        /**
          * The phone number as the user entered it.
          * <P>Type: TEXT</P>
          */
@@ -5055,6 +5066,18 @@
      * <td>Contact ID.</td>
      * </tr>
      * <tr>
+     * <td>long</td>
+     * <td>{@link #CONTACT_ID}</td>
+     * <td>read-only</td>
+     * <td>Contact ID.</td>
+     * </tr>
+     * <tr>
+     * <td>long</td>
+     * <td>{@link #DATA_ID}</td>
+     * <td>read-only</td>
+     * <td>Data ID.</td>
+     * </tr>
+     * <tr>
      * <td>String</td>
      * <td>{@link #LOOKUP_KEY}</td>
      * <td>read-only</td>
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 8468040..3700098 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -39,6 +39,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.ParcelFileDescriptor.OnCloseListener;
 import android.os.RemoteException;
+import android.os.storage.StorageVolume;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.util.Log;
@@ -62,7 +63,8 @@
  * All client apps must hold a valid URI permission grant to access documents,
  * typically issued when a user makes a selection through
  * {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT},
- * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, or {@link Intent#ACTION_OPEN_EXTERNAL_DIRECTORY}.
+ * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, or
+ * {@link StorageVolume#createAccessIntent(String) StorageVolume.createAccessIntent}.
  *
  * @see DocumentsProvider
  */
@@ -358,6 +360,7 @@
          * @see #COLUMN_MIME_TYPE
          * @see DocumentsProvider#openTypedDocument(String, String, Bundle,
          *      android.os.CancellationSignal)
+         * @see DocumentsProvider#getDocumentStreamTypes(String, String)
          */
         public static final int FLAG_VIRTUAL_DOCUMENT = 1 << 9;
 
@@ -1201,7 +1204,7 @@
         final ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
                 sourceDocumentUri.getAuthority());
         try {
-            return moveDocument(client, sourceParentDocumentUri, sourceDocumentUri,
+            return moveDocument(client, sourceDocumentUri, sourceParentDocumentUri,
                     targetParentDocumentUri);
         } catch (Exception e) {
             Log.w(TAG, "Failed to move document", e);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 2250629..515f975 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -316,7 +316,7 @@
      * @param parentDocumentId the parent of the document to move.
      */
     @SuppressWarnings("unused")
-    public boolean removeDocument(String documentId, String parentDocumentId)
+    public void removeDocument(String documentId, String parentDocumentId)
             throws FileNotFoundException {
         throw new UnsupportedOperationException("Remove not supported");
     }
@@ -540,6 +540,7 @@
      *            provider.
      * @param signal used by the caller to signal if the request should be
      *            cancelled. May be null.
+     * @see #getDocumentStreamTypes(String, String)
      */
     @SuppressWarnings("unused")
     public AssetFileDescriptor openTypedDocument(
@@ -926,6 +927,7 @@
      *
      * @see #openDocumentThumbnail(String, Point, CancellationSignal)
      * @see #openTypedDocument(String, String, Bundle, CancellationSignal)
+     * @see #getDocumentStreamTypes(String, String)
      */
     @Override
     public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
@@ -938,6 +940,7 @@
      *
      * @see #openDocumentThumbnail(String, Point, CancellationSignal)
      * @see #openTypedDocument(String, String, Bundle, CancellationSignal)
+     * @see #getDocumentStreamTypes(String, String)
      */
     @Override
     public final AssetFileDescriptor openTypedAssetFile(
@@ -947,6 +950,55 @@
     }
 
     /**
+     * Return a list of streamable MIME types matching the filter, which can be passed to
+     * {@link #openTypedDocument(String, String, Bundle, CancellationSignal)}.
+     *
+     * <p>The default implementation returns a MIME type provided by
+     * {@link #queryDocument(String, String[])} as long as it matches the filter and the document
+     * does not have the {@link Document#FLAG_VIRTUAL_DOCUMENT} flag set.
+     *
+     * @see #getStreamTypes(Uri, String)
+     * @see #openTypedDocument(String, String, Bundle, CancellationSignal)
+     */
+    public String[] getDocumentStreamTypes(String documentId, String mimeTypeFilter) {
+        Cursor cursor = null;
+        try {
+            cursor = queryDocument(documentId, null);
+            if (cursor.moveToFirst()) {
+                final String mimeType =
+                    cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE));
+                final long flags =
+                    cursor.getLong(cursor.getColumnIndexOrThrow(Document.COLUMN_FLAGS));
+                if ((flags & Document.FLAG_VIRTUAL_DOCUMENT) == 0 && mimeType != null &&
+                        mimeTypeMatches(mimeTypeFilter, mimeType)) {
+                    return new String[] { mimeType };
+                }
+            }
+        } catch (FileNotFoundException e) {
+            return null;
+        } finally {
+            IoUtils.closeQuietly(cursor);
+        }
+
+        // No streamable MIME types.
+        return null;
+    }
+
+    /**
+     * Called by a client to determine the types of data streams that this content provider
+     * support for the given URI.
+     *
+     * <p>Overriding this method is deprecated. Override {@link #openTypedDocument} instead.
+     *
+     * @see #getDocumentStreamTypes(String, String)
+     */
+    @Override
+    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
+        enforceTree(uri);
+        return getDocumentStreamTypes(getDocumentId(uri), mimeTypeFilter);
+    }
+
+    /**
      * @hide
      */
     private final AssetFileDescriptor openTypedAssetFileImpl(
@@ -971,4 +1023,21 @@
         // For any other yet unhandled case, let the provider subclass handle it.
         return openTypedDocument(documentId, mimeTypeFilter, opts, signal);
     }
+
+    /**
+     * @hide
+     */
+    public static boolean mimeTypeMatches(String filter, String test) {
+        if (test == null) {
+            return false;
+        } else if (filter == null || "*/*".equals(filter)) {
+            return true;
+        } else if (filter.equals(test)) {
+            return true;
+        } else if (filter.endsWith("/*")) {
+            return filter.regionMatches(0, test, 0, filter.indexOf('/'));
+        } else {
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7830142..5ab2b00 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -201,6 +201,21 @@
             "android.settings.ACCESSIBILITY_SETTINGS";
 
     /**
+     * Activity Action: Launch the screen reader tutorial.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_SCREEN_READER_TUTORIAL =
+            "android.settings.SCREEN_READER_TUTORIAL";
+
+
+    /**
      * Activity Action: Show settings to control access to usage information.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -4660,6 +4675,14 @@
                 "lock_screen_allow_private_notifications";
 
         /**
+         * When set by a user, allows notification remote input atop a securely locked screen
+         * without having to unlock
+         * @hide
+         */
+        public static final String LOCK_SCREEN_ALLOW_REMOTE_INPUT =
+                "lock_screen_allow_remote_input";
+
+        /**
          * Set by the system to track if the user needs to see the call to action for
          * the lockscreen notification policy.
          * @hide
@@ -5139,14 +5162,6 @@
         public static final String TTS_DEFAULT_SYNTH = "tts_default_synth";
 
         /**
-         * Whether text-to-speech higher speech rate is enabled.
-         * 0 = disabled.
-         * 1 = enabled.
-         * @hide
-         */
-        public static final String TTS_DEFAULT_HIGHER_SPEECH_RATE_ENABLED =
-            "tts_default_higher_speech_rate_enabled";
-        /**
          * Default text-to-speech language.
          *
          * @deprecated this setting is no longer in use, as of the Ice Cream
@@ -5907,13 +5922,6 @@
                 "camera_double_tap_power_gesture_disabled";
 
         /**
-         * Name of the package used as WebView provider (if unset the provider is instead determined
-         * by the system).
-         * @hide
-         */
-        public static final String WEBVIEW_PROVIDER = "webview_provider";
-
-        /**
          * This are the settings to be backed up.
          *
          * NOTE: Settings are backed up and restored in the order they appear
@@ -5958,7 +5966,6 @@
             ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
             TTS_USE_DEFAULTS,
             TTS_DEFAULT_RATE,
-            TTS_DEFAULT_HIGHER_SPEECH_RATE_ENABLED,
             TTS_DEFAULT_PITCH,
             TTS_DEFAULT_SYNTH,
             TTS_DEFAULT_LANG,
@@ -6724,6 +6731,16 @@
        public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
 
        /**
+        * Whether to disable the automatic scheduling of system updates.
+        * 1 = system updates won't be automatically scheduled (will always
+        * present notification instead).
+        * 0 = system updates will be automatically scheduled. (default)
+        * @hide
+        */
+       @SystemApi
+       public static final String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
+
+       /**
         * Whether the package manager should send package verification broadcasts for verifiers to
         * review apps prior to installation.
         * 1 = request apps to be verified prior to installation, if a verifier exists.
@@ -6940,6 +6957,13 @@
         public static final String WEBVIEW_DATA_REDUCTION_PROXY_KEY =
                 "webview_data_reduction_proxy_key";
 
+        /**
+         * Name of the package used as WebView provider (if unset the provider is instead determined
+         * by the system).
+         * @hide
+         */
+        public static final String WEBVIEW_PROVIDER = "webview_provider";
+
        /**
         * Whether Wifi display is enabled/disabled
         * 0=disabled. 1=enabled.
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index 7cf1d71..8689dce 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -19,6 +19,7 @@
 import android.security.keymaster.ExportResult;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keymaster.KeymasterBlob;
 import android.security.keymaster.OperationResult;
 import android.security.KeystoreArguments;
@@ -74,4 +75,5 @@
     int addAuthToken(in byte[] authToken);
     int onUserAdded(int userId, int parentId);
     int onUserRemoved(int userId);
+    int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);
 }
diff --git a/libs/hwui/FrameStatsObserver.h b/core/java/android/security/keymaster/KeymasterCertificateChain.aidl
similarity index 68%
copy from libs/hwui/FrameStatsObserver.h
copy to core/java/android/security/keymaster/KeymasterCertificateChain.aidl
index 7abc9f1..dc1876a 100644
--- a/libs/hwui/FrameStatsObserver.h
+++ b/core/java/android/security/keymaster/KeymasterCertificateChain.aidl
@@ -14,19 +14,7 @@
  * limitations under the License.
  */
 
-#pragma once
+package android.security.keymaster;
 
-#include <utils/RefBase.h>
-
-#include "BufferPool.h"
-
-namespace android {
-namespace uirenderer {
-
-class FrameStatsObserver : public VirtualLightRefBase {
-public:
-    virtual void notify(BufferPool::Buffer* buffer);
-};
-
-}; // namespace uirenderer
-}; // namespace android
+/* @hide */
+parcelable KeymasterCertificateChain;
diff --git a/core/java/android/security/keymaster/KeymasterCertificateChain.java b/core/java/android/security/keymaster/KeymasterCertificateChain.java
new file mode 100644
index 0000000..243b9fe
--- /dev/null
+++ b/core/java/android/security/keymaster/KeymasterCertificateChain.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keymaster;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for the Java side of keystore-generated certificate chains.
+ *
+ * Serialization code for this must be kept in sync with system/security/keystore
+ * @hide
+ */
+public class KeymasterCertificateChain implements Parcelable {
+
+    private List<byte[]> mCertificates;
+
+    public static final Parcelable.Creator<KeymasterCertificateChain> CREATOR = new
+            Parcelable.Creator<KeymasterCertificateChain>() {
+                public KeymasterCertificateChain createFromParcel(Parcel in) {
+                    return new KeymasterCertificateChain(in);
+                }
+                public KeymasterCertificateChain[] newArray(int size) {
+                    return new KeymasterCertificateChain[size];
+                }
+            };
+
+    public KeymasterCertificateChain() {
+        mCertificates = null;
+    }
+
+    public KeymasterCertificateChain(List<byte[]> mCertificates) {
+        this.mCertificates = mCertificates;
+    }
+
+    private KeymasterCertificateChain(Parcel in) {
+        readFromParcel(in);
+    }
+
+    public List<byte[]> getCertificates() {
+        return mCertificates;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        if (mCertificates == null) {
+            out.writeInt(0);
+        } else {
+            out.writeInt(mCertificates.size());
+            for (byte[] arg : mCertificates) {
+                out.writeByteArray(arg);
+            }
+        }
+    }
+
+    public void readFromParcel(Parcel in) {
+        int length = in.readInt();
+        mCertificates = new ArrayList<byte[]>(length);
+        for (int i = 0; i < length; i++) {
+            mCertificates.add(in.createByteArray());
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 04d5952..e01f2a0 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -58,6 +58,8 @@
     public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 705;
 
     public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_ULONG | 200;
+    public static final int KM_TAG_INCLUDE_UNIQUE_ID = KM_BOOL | 202;
+
     public static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400;
     public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401;
     public static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402;
@@ -74,11 +76,12 @@
     public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600;
     public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601;
 
-    public static final int KM_TAG_APPLICATION_DATA = KM_BYTES | 700;
     public static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701;
     public static final int KM_TAG_ORIGIN = KM_ENUM | 702;
     public static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703;
     public static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704;
+    public static final int KM_TAG_UNIQUE_ID = KM_BYTES | 707;
+    public static final int KM_TAG_ATTESTATION_CHALLENGE = KM_BYTES | 708;
 
     public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000;
     public static final int KM_TAG_NONCE = KM_BYTES | 1001;
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index 982ed68..81cad79 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -40,6 +40,9 @@
     // TODO: Replace this with a general X509TrustManager and use duck-typing.
     private final TrustManagerImpl mDelegate;
     private final NetworkSecurityConfig mNetworkSecurityConfig;
+    private final Object mIssuersLock = new Object();
+
+    private X509Certificate[] mIssuers;
 
     public NetworkSecurityTrustManager(NetworkSecurityConfig config) {
         if (config == null) {
@@ -139,6 +142,19 @@
 
     @Override
     public X509Certificate[] getAcceptedIssuers() {
-        return mDelegate.getAcceptedIssuers();
+        // TrustManagerImpl only looks at the provided KeyStore and not the TrustedCertificateStore
+        // for getAcceptedIssuers, so implement it here instead of delegating.
+        synchronized (mIssuersLock) {
+            if (mIssuers == null) {
+                Set<TrustAnchor> anchors = mNetworkSecurityConfig.getTrustAnchors();
+                X509Certificate[] issuers = new X509Certificate[anchors.size()];
+                int i = 0;
+                for (TrustAnchor anchor : anchors) {
+                    issuers[i++] = anchor.certificate;
+                }
+                mIssuers = issuers;
+            }
+            return mIssuers.clone();
+        }
     }
 }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 63853cb..97939a9 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -565,6 +565,10 @@
 
     private static boolean safeBoolean(XmlPullParser parser, String att, boolean defValue) {
         final String val = parser.getAttributeValue(null, att);
+        return safeBoolean(val, defValue);
+    }
+
+    private static boolean safeBoolean(String val, boolean defValue) {
         if (TextUtils.isEmpty(val)) return defValue;
         return Boolean.valueOf(val);
     }
@@ -802,6 +806,7 @@
                 .appendQueryParameter("days", toDayList(schedule.days))
                 .appendQueryParameter("start", schedule.startHour + "." + schedule.startMinute)
                 .appendQueryParameter("end", schedule.endHour + "." + schedule.endMinute)
+                .appendQueryParameter("exitAtAlarm", String.valueOf(schedule.exitAtAlarm))
                 .build();
     }
 
@@ -825,6 +830,7 @@
         rt.startMinute = start[1];
         rt.endHour = end[0];
         rt.endMinute = end[1];
+        rt.exitAtAlarm = safeBoolean(conditionId.getQueryParameter("exitAtAlarm"), false);
         return rt;
     }
 
@@ -838,6 +844,8 @@
         public int startMinute;
         public int endHour;
         public int endMinute;
+        public boolean exitAtAlarm;
+        public long nextAlarm;
 
         @Override
         public int hashCode() {
@@ -852,7 +860,8 @@
                     && startHour == other.startHour
                     && startMinute == other.startMinute
                     && endHour == other.endHour
-                    && endMinute == other.endMinute;
+                    && endMinute == other.endMinute
+                    && exitAtAlarm == other.exitAtAlarm;
         }
 
         public ScheduleInfo copy() {
@@ -865,6 +874,8 @@
             rt.startMinute = startMinute;
             rt.endHour = endHour;
             rt.endMinute = endMinute;
+            rt.exitAtAlarm = exitAtAlarm;
+            rt.nextAlarm = nextAlarm;
             return rt;
         }
     }
diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java
index 675803c..707c0fc 100644
--- a/core/java/android/text/BidiFormatter.java
+++ b/core/java/android/text/BidiFormatter.java
@@ -16,6 +16,7 @@
 
 package android.text;
 
+import android.annotation.Nullable;
 import android.view.View;
 
 import static android.text.TextDirectionHeuristics.FIRSTSTRONG_LTR;
@@ -390,14 +391,17 @@
      * @return Input string after applying the above processing. {@code null} if {@code str} is
      *     {@code null}.
      */
-    public String unicodeWrap(String str, TextDirectionHeuristic heuristic, boolean isolate) {
+    public @Nullable String unicodeWrap(@Nullable String str, TextDirectionHeuristic heuristic,
+            boolean isolate) {
+        if (str == null) return null;
         return unicodeWrap((CharSequence) str, heuristic, isolate).toString();
     }
 
     /**
      * @hide
      */
-    public CharSequence unicodeWrap(CharSequence str, TextDirectionHeuristic heuristic, boolean isolate) {
+    public @Nullable CharSequence unicodeWrap(@Nullable CharSequence str,
+            TextDirectionHeuristic heuristic, boolean isolate) {
         if (str == null) return null;
         final boolean isRtl = heuristic.isRtl(str, 0, str.length());
         SpannableStringBuilder result = new SpannableStringBuilder();
diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java
index fd9188b..0f65f80 100644
--- a/core/java/android/text/BoringLayout.java
+++ b/core/java/android/text/BoringLayout.java
@@ -189,12 +189,6 @@
 
         mBottom = spacing;
 
-        if (includepad) {
-            mDesc = spacing + metrics.top;
-        } else {
-            mDesc = spacing + metrics.ascent;
-        }
-
         if (trustWidth) {
             mMax = metrics.width;
         } else {
@@ -214,6 +208,8 @@
             mTopPadding = metrics.top - metrics.ascent;
             mBottomPadding = metrics.bottom - metrics.descent;
         }
+
+        mDesc = spacing + mBottomPadding + (includepad ? metrics.top : metrics.ascent);
     }
 
     /**
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
new file mode 100644
index 0000000..b437f48
--- /dev/null
+++ b/core/java/android/text/Emoji.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import java.util.Arrays;
+
+/**
+ * An utility class for Emoji.
+ * @hide
+ */
+public class Emoji {
+    // See http://www.unicode.org/Public/emoji/2.0//emoji-data.txt
+    private static int[] EMOJI_MODIFIER_BASE = {
+        0x261D, 0x26F9, 0x270A, 0x270B, 0x270C, 0x270D, 0x1F385, 0x1F3C3, 0x1F3C4, 0x1F3CA,
+        0x1F3CB, 0x1F442, 0x1F443, 0x1F446, 0x1F447, 0x1F448, 0x1F449, 0x1F44A, 0x1F44B, 0x1F44C,
+        0x1F44D, 0x1F44E, 0x1F44F, 0x1F450, 0x1F466, 0x1F467, 0x1F468, 0x1F469, 0x1F46E, 0x1F470,
+        0x1F471, 0x1F472, 0x1F473, 0x1F474, 0x1F475, 0x1F476, 0x1F474, 0x1F478, 0x1F47C, 0x1F481,
+        0x1F482, 0x1F483, 0x1F485, 0x1F486, 0x1F487, 0x1F4AA, 0x1F575, 0x1F590, 0x1F595, 0x1F596,
+        0x1F645, 0x1F646, 0x1F647, 0x1F64B, 0x1F64C, 0x1F64D, 0x1F64E, 0x1F64F, 0x1F6A3, 0x1F6B4,
+        0x1F6B5, 0x1F6B6, 0x1F6C0, 0x1F918
+    };
+
+    // See http://www.unicode.org/emoji/charts/emoji-zwj-sequences.html
+    private static int[] ZWJ_EMOJI = {
+        0x2764, 0x1F441, 0x1F466, 0x1F467, 0x1F468, 0x1F469, 0x1F48B, 0x1F5E8
+    };
+
+    public static int COMBINING_ENCLOSING_KEYCAP = 0x20E3;
+
+    public static int ZERO_WIDTH_JOINER = 0x200D;
+
+    public static int VARIATION_SELECTOR_16 = 0xFE0F;
+
+    // Returns true if the given code point is regional indicator symbol.
+    public static boolean isRegionalIndicatorSymbol(int codepoint) {
+        return 0x1F1E6 <= codepoint && codepoint <= 0x1F1FF;
+    }
+
+    // Returns true if the given code point is emoji modifier.
+    public static boolean isEmojiModifier(int codepoint) {
+        return 0x1F3FB <= codepoint && codepoint <= 0x1F3FF;
+    }
+
+    // Returns true if the given code point is emoji modifier base.
+    public static boolean isEmojiModifierBase(int codePoint) {
+        return Arrays.binarySearch(EMOJI_MODIFIER_BASE, codePoint) >= 0;
+    }
+
+    // Returns true if the character appears before or after zwj in a zwj emoji sequence.
+    public static boolean isZwjEmoji(int codePoint) {
+        return Arrays.binarySearch(ZWJ_EMOJI, codePoint) >= 0;
+    }
+
+    // Returns true if the character can be a base character of COMBINING ENCLOSING KEYCAP.
+    public static boolean isKeycapBase(int codePoint) {
+        return ('0' <= codePoint && codePoint <= '9') || codePoint == '#' || codePoint == '*';
+    }
+}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index ed91239c..409994d 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -54,6 +54,11 @@
 
 import java.io.IOException;
 import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * This class processes HTML strings into displayable styled text.
@@ -354,24 +359,48 @@
         }
     }
 
-    private static String getTextStyles(Spanned text, int start, int end) {
-        final StringBuilder style = new StringBuilder(" style=\"margin-top:0; margin-bottom:0;");
+    private static String getTextStyles(Spanned text, int start, int end,
+            boolean forceNoVerticalMargin, boolean includeTextAlign) {
+        String margin = null;
+        String textAlign = null;
 
-        final AlignmentSpan[] alignmentSpans = text.getSpans(start, end, AlignmentSpan.class);
-        final int len = alignmentSpans.length;
-        if (len > 0) {
-            final Layout.Alignment alignment = alignmentSpans[len - 1].getAlignment();
-            if (alignment == Layout.Alignment.ALIGN_NORMAL) {
-                style.append(" text-align:start;");
-            } else if (alignment == Layout.Alignment.ALIGN_CENTER) {
-                style.append(" text-align:center;");
-            } else if (alignment == Layout.Alignment.ALIGN_OPPOSITE) {
-                style.append(" text-align:end;");
+        if (forceNoVerticalMargin) {
+            margin = "margin-top:0; margin-bottom:0;";
+        }
+        if (includeTextAlign) {
+            final AlignmentSpan[] alignmentSpans = text.getSpans(start, end, AlignmentSpan.class);
+
+            // Only use the last AlignmentSpan with flag SPAN_PARAGRAPH
+            for (int i = alignmentSpans.length - 1; i >= 0; i--) {
+                AlignmentSpan s = alignmentSpans[i];
+                if ((text.getSpanFlags(s) & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH) {
+                    final Layout.Alignment alignment = s.getAlignment();
+                    if (alignment == Layout.Alignment.ALIGN_NORMAL) {
+                        textAlign = "text-align:start;";
+                    } else if (alignment == Layout.Alignment.ALIGN_CENTER) {
+                        textAlign = "text-align:center;";
+                    } else if (alignment == Layout.Alignment.ALIGN_OPPOSITE) {
+                        textAlign = "text-align:end;";
+                    }
+                    break;
+                }
             }
         }
 
-        style.append("\"");
-        return style.toString();
+        if (margin == null && textAlign == null) {
+            return "";
+        }
+
+        final StringBuilder style = new StringBuilder(" style=\"");
+        if (margin != null && textAlign != null) {
+            style.append(margin).append(" ").append(textAlign);
+        } else if (margin != null) {
+            style.append(margin);
+        } else if (textAlign != null) {
+            style.append(textAlign);
+        }
+
+        return style.append("\"").toString();
     }
 
     private static void withinBlockquote(StringBuilder out, Spanned text, int start, int end,
@@ -393,46 +422,55 @@
                 next = end;
             }
 
-            boolean isListItem = false;
-            ParagraphStyle[] paragraphStyles = text.getSpans(i, next, ParagraphStyle.class);
-            for (ParagraphStyle paragraphStyle : paragraphStyles) {
-                final int spanFlags = text.getSpanFlags(paragraphStyle);
-                if ((spanFlags & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH
-                        && paragraphStyle instanceof BulletSpan) {
-                    isListItem = true;
-                    break;
+            if (next == i) {
+                if (isInList) {
+                    // Current paragraph is no longer a list item; close the previously opened list
+                    isInList = false;
+                    out.append("</ul>\n");
                 }
-            }
-
-            if (isListItem && !isInList) {
-                // Current paragraph is the first item in a list
-                isInList = true;
-                out.append("<ul>\n");
-            }
-
-            if (isInList && !isListItem) {
-                // Current paragraph is no longer a list item; close the previously opened list
-                isInList = false;
-                out.append("</ul>\n");
-            }
-
-            String tagType = isListItem ? "li" : "p";
-            out.append("<").append(tagType).append(getTextDirection(text, start, next))
-                    .append(getTextStyles(text, start, next)).append(">");
-
-            if (next - i == 0) {
-                out.append("<br>");
+                out.append("<br>\n");
             } else {
+                boolean isListItem = false;
+                ParagraphStyle[] paragraphStyles = text.getSpans(i, next, ParagraphStyle.class);
+                for (ParagraphStyle paragraphStyle : paragraphStyles) {
+                    final int spanFlags = text.getSpanFlags(paragraphStyle);
+                    if ((spanFlags & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH
+                            && paragraphStyle instanceof BulletSpan) {
+                        isListItem = true;
+                        break;
+                    }
+                }
+
+                if (isListItem && !isInList) {
+                    // Current paragraph is the first item in a list
+                    isInList = true;
+                    out.append("<ul")
+                            .append(getTextStyles(text, i, next, true, false))
+                            .append(">\n");
+                }
+
+                if (isInList && !isListItem) {
+                    // Current paragraph is no longer a list item; close the previously opened list
+                    isInList = false;
+                    out.append("</ul>\n");
+                }
+
+                String tagType = isListItem ? "li" : "p";
+                out.append("<").append(tagType)
+                        .append(getTextDirection(text, i, next))
+                        .append(getTextStyles(text, i, next, !isListItem, true))
+                        .append(">");
+
                 withinParagraph(out, text, i, next);
-            }
 
-            out.append("</");
-            out.append(tagType);
-            out.append(">\n");
+                out.append("</");
+                out.append(tagType);
+                out.append(">\n");
 
-            if (next == end && isInList) {
-                isInList = false;
-                out.append("</ul>\n");
+                if (next == end && isInList) {
+                    isInList = false;
+                    out.append("</ul>\n");
+                }
             }
 
             next++;
@@ -640,7 +678,7 @@
 
 class HtmlToSpannedConverter implements ContentHandler {
 
-    private static final float[] HEADER_SIZES = {
+    private static final float[] HEADING_SIZES = {
         1.5f, 1.4f, 1.3f, 1.2f, 1.1f, 1f,
     };
 
@@ -651,6 +689,58 @@
     private Html.TagHandler mTagHandler;
     private int mFlags;
 
+    private static Pattern sTextAlignPattern;
+    private static Pattern sForegroundColorPattern;
+    private static Pattern sBackgroundColorPattern;
+    private static Pattern sTextDecorationPattern;
+
+    /**
+     * Name-value mapping of HTML/CSS colors which have different values in {@link Color}.
+     */
+    private static final Map<String, Integer> sColorMap;
+
+    static {
+        sColorMap = new HashMap<>();
+        sColorMap.put("darkgray", 0xFFA9A9A9);
+        sColorMap.put("gray", 0xFF808080);
+        sColorMap.put("lightgray", 0xFFD3D3D3);
+        sColorMap.put("darkgrey", 0xFFA9A9A9);
+        sColorMap.put("grey", 0xFF808080);
+        sColorMap.put("lightgrey", 0xFFD3D3D3);
+        sColorMap.put("green", 0xFF008000);
+    }
+
+    private static Pattern getTextAlignPattern() {
+        if (sTextAlignPattern == null) {
+            sTextAlignPattern = Pattern.compile("(?:\\s+|\\A)text-align\\s*:\\s*(\\S*)\\b");
+        }
+        return sTextAlignPattern;
+    }
+
+    private static Pattern getForegroundColorPattern() {
+        if (sForegroundColorPattern == null) {
+            sForegroundColorPattern = Pattern.compile(
+                    "(?:\\s+|\\A)color\\s*:\\s*(\\S*)\\b");
+        }
+        return sForegroundColorPattern;
+    }
+
+    private static Pattern getBackgroundColorPattern() {
+        if (sBackgroundColorPattern == null) {
+            sBackgroundColorPattern = Pattern.compile(
+                    "(?:\\s+|\\A)background(?:-color)?\\s*:\\s*(\\S*)\\b");
+        }
+        return sBackgroundColorPattern;
+    }
+
+    private static Pattern getTextDecorationPattern() {
+        if (sTextDecorationPattern == null) {
+            sTextDecorationPattern = Pattern.compile(
+                    "(?:\\s+|\\A)text-decoration\\s*:\\s*(\\S*)\\b");
+        }
+        return sTextDecorationPattern;
+    }
+
     public HtmlToSpannedConverter( String source, Html.ImageGetter imageGetter,
             Html.TagHandler tagHandler, Parser parser, int flags) {
         mSource = source;
@@ -701,11 +791,18 @@
     private void handleStartTag(String tag, Attributes attributes) {
         if (tag.equalsIgnoreCase("br")) {
             // We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>
-            // so we can safely emite the linebreaks when we handle the close tag.
+            // so we can safely emit the linebreaks when we handle the close tag.
         } else if (tag.equalsIgnoreCase("p")) {
-            handleP(mSpannableStringBuilder);
+            startBlockElement(mSpannableStringBuilder, attributes, getMarginParagraph());
+            startCssStyle(mSpannableStringBuilder, attributes);
+        } else if (tag.equalsIgnoreCase("ul")) {
+            startBlockElement(mSpannableStringBuilder, attributes, getMarginList());
+        } else if (tag.equalsIgnoreCase("li")) {
+            startLi(mSpannableStringBuilder, attributes);
         } else if (tag.equalsIgnoreCase("div")) {
-            handleP(mSpannableStringBuilder);
+            startBlockElement(mSpannableStringBuilder, attributes, getMarginDiv());
+        } else if (tag.equalsIgnoreCase("span")) {
+            startCssStyle(mSpannableStringBuilder, attributes);
         } else if (tag.equalsIgnoreCase("strong")) {
             start(mSpannableStringBuilder, new Bold());
         } else if (tag.equalsIgnoreCase("b")) {
@@ -725,8 +822,7 @@
         } else if (tag.equalsIgnoreCase("font")) {
             startFont(mSpannableStringBuilder, attributes);
         } else if (tag.equalsIgnoreCase("blockquote")) {
-            handleP(mSpannableStringBuilder);
-            start(mSpannableStringBuilder, new Blockquote());
+            startBlockquote(mSpannableStringBuilder, attributes);
         } else if (tag.equalsIgnoreCase("tt")) {
             start(mSpannableStringBuilder, new Monospace());
         } else if (tag.equalsIgnoreCase("a")) {
@@ -744,10 +840,9 @@
         } else if (tag.equalsIgnoreCase("sub")) {
             start(mSpannableStringBuilder, new Sub());
         } else if (tag.length() == 2 &&
-                   Character.toLowerCase(tag.charAt(0)) == 'h' &&
-                   tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
-            handleP(mSpannableStringBuilder);
-            start(mSpannableStringBuilder, new Header(tag.charAt(1) - '1'));
+                Character.toLowerCase(tag.charAt(0)) == 'h' &&
+                tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
+            startHeading(mSpannableStringBuilder, attributes, tag.charAt(1) - '1');
         } else if (tag.equalsIgnoreCase("img")) {
             startImg(mSpannableStringBuilder, attributes, mImageGetter);
         } else if (mTagHandler != null) {
@@ -759,9 +854,16 @@
         if (tag.equalsIgnoreCase("br")) {
             handleBr(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("p")) {
-            handleP(mSpannableStringBuilder);
+            endCssStyle(mSpannableStringBuilder);
+            endBlockElement(mSpannableStringBuilder);
+        } else if (tag.equalsIgnoreCase("ul")) {
+            endBlockElement(mSpannableStringBuilder);
+        } else if (tag.equalsIgnoreCase("li")) {
+            endLi(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("div")) {
-            handleP(mSpannableStringBuilder);
+            endBlockElement(mSpannableStringBuilder);
+        } else if (tag.equalsIgnoreCase("span")) {
+            endCssStyle(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("strong")) {
             end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD));
         } else if (tag.equalsIgnoreCase("b")) {
@@ -781,11 +883,9 @@
         } else if (tag.equalsIgnoreCase("font")) {
             endFont(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("blockquote")) {
-            handleP(mSpannableStringBuilder);
-            end(mSpannableStringBuilder, Blockquote.class, new QuoteSpan());
+            endBlockquote(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("tt")) {
-            end(mSpannableStringBuilder, Monospace.class,
-                    new TypefaceSpan("monospace"));
+            end(mSpannableStringBuilder, Monospace.class, new TypefaceSpan("monospace"));
         } else if (tag.equalsIgnoreCase("a")) {
             endA(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("u")) {
@@ -803,40 +903,151 @@
         } else if (tag.length() == 2 &&
                 Character.toLowerCase(tag.charAt(0)) == 'h' &&
                 tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
-            handleP(mSpannableStringBuilder);
-            endHeader(mSpannableStringBuilder);
+            endHeading(mSpannableStringBuilder);
         } else if (mTagHandler != null) {
             mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader);
         }
     }
 
-    private static void handleP(SpannableStringBuilder text) {
-        int len = text.length();
+    private int getMarginParagraph() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH);
+    }
 
-        if (len >= 1 && text.charAt(len - 1) == '\n') {
-            if (len >= 2 && text.charAt(len - 2) == '\n') {
-                return;
-            }
+    private int getMarginHeading() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING);
+    }
 
-            text.append("\n");
+    private int getMarginListItem() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM);
+    }
+
+    private int getMarginList() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST);
+    }
+
+    private int getMarginDiv() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_DIV);
+    }
+
+    private int getMarginBlockquote() {
+        return getMargin(Html.FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE);
+    }
+
+    /**
+     * Returns the minimum number of newline characters needed before and after a given block-level
+     * element.
+     *
+     * @param flag the corresponding option flag defined in {@link Html} of a block-level element
+     */
+    private int getMargin(int flag) {
+        if ((flag & mFlags) != 0) {
+            return 1;
+        }
+        return 2;
+    }
+
+    private static void appendNewlines(Editable text, int minNewline) {
+        final int len = text.length();
+
+        if (len == 0) {
             return;
         }
 
-        if (len != 0) {
-            text.append("\n\n");
+        int existingNewlines = 0;
+        for (int i = len - 1; i >= 0 && text.charAt(i) == '\n'; i--) {
+            existingNewlines++;
+        }
+
+        for (int j = existingNewlines; j < minNewline; j++) {
+            text.append("\n");
         }
     }
 
-    private static void handleBr(SpannableStringBuilder text) {
-        text.append("\n");
+    private static void startBlockElement(Editable text, Attributes attributes, int margin) {
+        final int len = text.length();
+        if (margin > 0) {
+            appendNewlines(text, margin);
+            start(text, new Newline(margin));
+        }
+
+        String style = attributes.getValue("", "style");
+        if (style != null) {
+            Matcher m = getTextAlignPattern().matcher(style);
+            if (m.find()) {
+                String alignment = m.group(1);
+                if (alignment.equalsIgnoreCase("start")) {
+                    start(text, new Alignment(Layout.Alignment.ALIGN_NORMAL));
+                } else if (alignment.equalsIgnoreCase("center")) {
+                    start(text, new Alignment(Layout.Alignment.ALIGN_CENTER));
+                } else if (alignment.equalsIgnoreCase("end")) {
+                    start(text, new Alignment(Layout.Alignment.ALIGN_OPPOSITE));
+                }
+            }
+        }
     }
 
-    private static Object getLast(Spanned text, Class kind) {
+    private static void endBlockElement(Editable text) {
+        Newline n = getLast(text, Newline.class);
+        if (n != null) {
+            appendNewlines(text, n.mNumNewlines);
+            text.removeSpan(n);
+        }
+
+        Alignment a = getLast(text, Alignment.class);
+        if (a != null) {
+            setSpanFromMark(text, a, new AlignmentSpan.Standard(a.mAlignment));
+        }
+    }
+
+    private static void handleBr(Editable text) {
+        text.append('\n');
+    }
+
+    private void startLi(Editable text, Attributes attributes) {
+        startBlockElement(text, attributes, getMarginListItem());
+        start(text, new Bullet());
+        startCssStyle(text, attributes);
+    }
+
+    private static void endLi(Editable text) {
+        endCssStyle(text);
+        endBlockElement(text);
+        end(text, Bullet.class, new BulletSpan());
+    }
+
+    private void startBlockquote(Editable text, Attributes attributes) {
+        startBlockElement(text, attributes, getMarginBlockquote());
+        start(text, new Blockquote());
+    }
+
+    private static void endBlockquote(Editable text) {
+        endBlockElement(text);
+        end(text, Blockquote.class, new QuoteSpan());
+    }
+
+    private void startHeading(Editable text, Attributes attributes, int level) {
+        startBlockElement(text, attributes, getMarginHeading());
+        start(text, new Heading(level));
+    }
+
+    private static void endHeading(Editable text) {
+        // RelativeSizeSpan and StyleSpan are CharacterStyles
+        // Their ranges should not include the newlines at the end
+        Heading h = getLast(text, Heading.class);
+        if (h != null) {
+            setSpanFromMark(text, h, new RelativeSizeSpan(HEADING_SIZES[h.mLevel]),
+                    new StyleSpan(Typeface.BOLD));
+        }
+
+        endBlockElement(text);
+    }
+
+    private static <T> T getLast(Spanned text, Class<T> kind) {
         /*
          * This knows that the last returned object from getSpans()
          * will be the most recently added.
          */
-        Object[] objs = text.getSpans(0, text.length(), kind);
+        T[] objs = text.getSpans(0, text.length(), kind);
 
         if (objs.length == 0) {
             return null;
@@ -845,26 +1056,77 @@
         }
     }
 
-    private static void start(SpannableStringBuilder text, Object mark) {
+    private static void setSpanFromMark(Spannable text, Object mark, Object... spans) {
+        int where = text.getSpanStart(mark);
+        text.removeSpan(mark);
         int len = text.length();
-        text.setSpan(mark, len, len, Spannable.SPAN_MARK_MARK);
-    }
-
-    private static void end(SpannableStringBuilder text, Class kind,
-                            Object repl) {
-        int len = text.length();
-        Object obj = getLast(text, kind);
-        int where = text.getSpanStart(obj);
-
-        text.removeSpan(obj);
-
         if (where != len) {
-            text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            for (Object span : spans) {
+                text.setSpan(span, where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
         }
     }
 
-    private static void startImg(SpannableStringBuilder text,
-                                 Attributes attributes, Html.ImageGetter img) {
+    private static void start(Editable text, Object mark) {
+        int len = text.length();
+        text.setSpan(mark, len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+    }
+
+    private static void end(Editable text, Class kind, Object repl) {
+        int len = text.length();
+        Object obj = getLast(text, kind);
+        if (obj != null) {
+            setSpanFromMark(text, obj, repl);
+        }
+    }
+
+    private void startCssStyle(Editable text, Attributes attributes) {
+        String style = attributes.getValue("", "style");
+        if (style != null) {
+            Matcher m = getForegroundColorPattern().matcher(style);
+            if (m.find()) {
+                int c = getHtmlColor(m.group(1));
+                if (c != -1) {
+                    start(text, new Foreground(c | 0xFF000000));
+                }
+            }
+
+            m = getBackgroundColorPattern().matcher(style);
+            if (m.find()) {
+                int c = getHtmlColor(m.group(1));
+                if (c != -1) {
+                    start(text, new Background(c | 0xFF000000));
+                }
+            }
+
+            m = getTextDecorationPattern().matcher(style);
+            if (m.find()) {
+                String textDecoration = m.group(1);
+                if (textDecoration.equalsIgnoreCase("line-through")) {
+                    start(text, new Strikethrough());
+                }
+            }
+        }
+    }
+
+    private static void endCssStyle(Editable text) {
+        Strikethrough s = getLast(text, Strikethrough.class);
+        if (s != null) {
+            setSpanFromMark(text, s, new StrikethroughSpan());
+        }
+
+        Background b = getLast(text, Background.class);
+        if (b != null) {
+            setSpanFromMark(text, b, new BackgroundColorSpan(b.mBackgroundColor));
+        }
+
+        Foreground f = getLast(text, Foreground.class);
+        if (f != null) {
+            setSpanFromMark(text, f, new ForegroundColorSpan(f.mForegroundColor));
+        }
+    }
+
+    private static void startImg(Editable text, Attributes attributes, Html.ImageGetter img) {
         String src = attributes.getValue("", "src");
         Drawable d = null;
 
@@ -885,98 +1147,58 @@
                      Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
     }
 
-    private static void startFont(SpannableStringBuilder text,
-                                  Attributes attributes) {
+    private void startFont(Editable text, Attributes attributes) {
         String color = attributes.getValue("", "color");
         String face = attributes.getValue("", "face");
 
-        int len = text.length();
-        text.setSpan(new Font(color, face), len, len, Spannable.SPAN_MARK_MARK);
-    }
-
-    private static void endFont(SpannableStringBuilder text) {
-        int len = text.length();
-        Object obj = getLast(text, Font.class);
-        int where = text.getSpanStart(obj);
-
-        text.removeSpan(obj);
-
-        if (where != len) {
-            Font f = (Font) obj;
-
-            if (!TextUtils.isEmpty(f.mColor)) {
-                if (f.mColor.startsWith("@")) {
-                    Resources res = Resources.getSystem();
-                    String name = f.mColor.substring(1);
-                    int colorRes = res.getIdentifier(name, "color", "android");
-                    if (colorRes != 0) {
-                        ColorStateList colors = res.getColorStateList(colorRes, null);
-                        text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null),
-                                where, len,
-                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-                    }
-                } else {
-                    int c = Color.getHtmlColor(f.mColor);
-                    if (c != -1) {
-                        text.setSpan(new ForegroundColorSpan(c | 0xFF000000),
-                                where, len,
-                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-                    }
-                }
+        if (!TextUtils.isEmpty(color)) {
+            int c = getHtmlColor(color);
+            if (c != -1) {
+                start(text, new Foreground(c | 0xFF000000));
             }
+        }
 
-            if (f.mFace != null) {
-                text.setSpan(new TypefaceSpan(f.mFace), where, len,
-                             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
+        if (!TextUtils.isEmpty(face)) {
+            start(text, new Font(face));
         }
     }
 
-    private static void startA(SpannableStringBuilder text, Attributes attributes) {
+    private static void endFont(Editable text) {
+        Font font = getLast(text, Font.class);
+        if (font != null) {
+            setSpanFromMark(text, font, new TypefaceSpan(font.mFace));
+        }
+
+        Foreground foreground = getLast(text, Foreground.class);
+        if (foreground != null) {
+            setSpanFromMark(text, foreground,
+                    new ForegroundColorSpan(foreground.mForegroundColor));
+        }
+    }
+
+    private static void startA(Editable text, Attributes attributes) {
         String href = attributes.getValue("", "href");
-
-        int len = text.length();
-        text.setSpan(new Href(href), len, len, Spannable.SPAN_MARK_MARK);
+        start(text, new Href(href));
     }
 
-    private static void endA(SpannableStringBuilder text) {
-        int len = text.length();
-        Object obj = getLast(text, Href.class);
-        int where = text.getSpanStart(obj);
-
-        text.removeSpan(obj);
-
-        if (where != len) {
-            Href h = (Href) obj;
-
+    private static void endA(Editable text) {
+        Href h = getLast(text, Href.class);
+        if (h != null) {
             if (h.mHref != null) {
-                text.setSpan(new URLSpan(h.mHref), where, len,
-                             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                setSpanFromMark(text, h, new URLSpan((h.mHref)));
             }
         }
     }
 
-    private static void endHeader(SpannableStringBuilder text) {
-        int len = text.length();
-        Object obj = getLast(text, Header.class);
-
-        int where = text.getSpanStart(obj);
-
-        text.removeSpan(obj);
-
-        // Back off not to change only the text, not the blank line.
-        while (len > where && text.charAt(len - 1) == '\n') {
-            len--;
+    private int getHtmlColor(String color) {
+        if ((mFlags & Html.FROM_HTML_OPTION_USE_CSS_COLORS)
+                == Html.FROM_HTML_OPTION_USE_CSS_COLORS) {
+            Integer i = sColorMap.get(color.toLowerCase(Locale.US));
+            if (i != null) {
+                return i;
+            }
         }
-
-        if (where != len) {
-            Header h = (Header) obj;
-
-            text.setSpan(new RelativeSizeSpan(HEADER_SIZES[h.mLevel]),
-                         where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            text.setSpan(new StyleSpan(Typeface.BOLD),
-                         where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-        }
+        return Color.getHtmlColor(color);
     }
 
     public void setDocumentLocator(Locator locator) {
@@ -1060,13 +1282,12 @@
     private static class Blockquote { }
     private static class Super { }
     private static class Sub { }
+    private static class Bullet { }
 
     private static class Font {
-        public String mColor;
         public String mFace;
 
-        public Font(String color, String face) {
-            mColor = color;
+        public Font(String face) {
             mFace = face;
         }
     }
@@ -1079,11 +1300,43 @@
         }
     }
 
-    private static class Header {
+    private static class Foreground {
+        private int mForegroundColor;
+
+        public Foreground(int foregroundColor) {
+            mForegroundColor = foregroundColor;
+        }
+    }
+
+    private static class Background {
+        private int mBackgroundColor;
+
+        public Background(int backgroundColor) {
+            mBackgroundColor = backgroundColor;
+        }
+    }
+
+    private static class Heading {
         private int mLevel;
 
-        public Header(int level) {
+        public Heading(int level) {
             mLevel = level;
         }
     }
+
+    private static class Newline {
+        private int mNumNewlines;
+
+        public Newline(int numNewlines) {
+            mNumNewlines = numNewlines;
+        }
+    }
+
+    private static class Alignment {
+        private Layout.Alignment mAlignment;
+
+        public Alignment(Layout.Alignment alignment) {
+            mAlignment = alignment;
+        }
+    }
 }
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index fe7571f..367c9fb 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -16,13 +16,19 @@
 
 package android.text.method;
 
+import android.icu.lang.UCharacter;
+import android.icu.lang.UProperty;
 import android.view.KeyEvent;
 import android.view.View;
 import android.text.*;
 import android.text.method.TextKeyListener.Capitalize;
+import android.text.style.ReplacementSpan;
 import android.widget.TextView;
 
 import java.text.BreakIterator;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
 
 /**
  * Abstract base class for key listeners.
@@ -63,6 +69,213 @@
         return backspaceOrForwardDelete(view, content, keyCode, event, true);
     }
 
+    // Returns true if the given code point is a variation selector.
+    private static boolean isVariationSelector(int codepoint) {
+        return UCharacter.hasBinaryProperty(codepoint, UProperty.VARIATION_SELECTOR);
+    }
+
+    // Returns the offset of the replacement span edge if the offset is inside of the replacement
+    // span.  Otherwise, does nothing and returns the input offset value.
+    private static int adjustReplacementSpan(CharSequence text, int offset, boolean moveToStart) {
+        if (!(text instanceof Spanned)) {
+            return offset;
+        }
+
+        ReplacementSpan[] spans = ((Spanned) text).getSpans(offset, offset, ReplacementSpan.class);
+        for (int i = 0; i < spans.length; i++) {
+            final int start = ((Spanned) text).getSpanStart(spans[i]);
+            final int end = ((Spanned) text).getSpanEnd(spans[i]);
+
+            if (start < offset && end > offset) {
+                offset = moveToStart ? start : end;
+            }
+        }
+        return offset;
+    }
+
+    // Returns the start offset to be deleted by a backspace key from the given offset.
+    private static int getOffsetForBackspaceKey(CharSequence text, int offset) {
+        if (offset <= 1) {
+            return 0;
+        }
+
+        // Initial state
+        final int STATE_START = 0;
+
+        // The offset is immediately before a KEYCAP.
+        final int STATE_BEFORE_KEYCAP = 1;
+        // The offset is immediately before a variation selector and a KEYCAP.
+        final int STATE_BEFORE_VS_AND_KEYCAP = 2;
+
+        // The offset is immediately before an emoji modifier.
+        final int STATE_BEFORE_EMOJI_MODIFIER = 3;
+        // The offset is immediately before a variation selector and an emoji modifier.
+        final int STATE_BEFORE_VS_AND_EMOJI_MODIFIER = 4;
+
+        // The offset is immediately before a variation selector.
+        final int STATE_BEFORE_VS = 5;
+
+        // The offset is immediately before a ZWJ emoji.
+        final int STATE_BEFORE_ZWJ_EMOJI = 6;
+        // The offset is immediately before a ZWJ that were seen before a ZWJ emoji.
+        final int STATE_BEFORE_ZWJ = 7;
+        // The offset is immediately before a variation selector and a ZWJ that were seen before a
+        // ZWJ emoji.
+        final int STATE_BEFORE_VS_AND_ZWJ = 8;
+
+        // The number of following RIS code points is odd.
+        final int STATE_ODD_NUMBERED_RIS = 9;
+        // The number of following RIS code points is even.
+        final int STATE_EVEN_NUMBERED_RIS = 10;
+
+        // The state machine has been stopped.
+        final int STATE_FINISHED = 11;
+
+        int deleteCharCount = 0;  // Char count to be deleted by backspace.
+        int lastSeenVSCharCount = 0;  // Char count of previous variation selector.
+
+        int state = STATE_START;
+
+        int tmpOffset = offset;
+        do {
+            final int codePoint = Character.codePointBefore(text, tmpOffset);
+            tmpOffset -= Character.charCount(codePoint);
+
+            switch (state) {
+                case STATE_START:
+                    deleteCharCount = Character.charCount(codePoint);
+                    if (isVariationSelector(codePoint)) {
+                        state = STATE_BEFORE_VS;
+                    } else if (Emoji.isZwjEmoji(codePoint)) {
+                        state = STATE_BEFORE_ZWJ_EMOJI;
+                    } else if (Emoji.isRegionalIndicatorSymbol(codePoint)) {
+                        state = STATE_ODD_NUMBERED_RIS;
+                    } else if (Emoji.isEmojiModifier(codePoint)) {
+                        state = STATE_BEFORE_EMOJI_MODIFIER;
+                    } else if (codePoint == Emoji.COMBINING_ENCLOSING_KEYCAP) {
+                        state = STATE_BEFORE_KEYCAP;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                case STATE_ODD_NUMBERED_RIS:
+                    if (Emoji.isRegionalIndicatorSymbol(codePoint)) {
+                        deleteCharCount += 2; /* Char count of RIS */
+                        state = STATE_EVEN_NUMBERED_RIS;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                case STATE_EVEN_NUMBERED_RIS:
+                    if (Emoji.isRegionalIndicatorSymbol(codePoint)) {
+                        deleteCharCount -= 2; /* Char count of RIS */
+                        state = STATE_ODD_NUMBERED_RIS;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                case STATE_BEFORE_KEYCAP:
+                    if (isVariationSelector(codePoint)) {
+                        lastSeenVSCharCount = Character.charCount(codePoint);
+                        state = STATE_BEFORE_VS_AND_KEYCAP;
+                        break;
+                    }
+
+                    if (Emoji.isKeycapBase(codePoint)) {
+                        deleteCharCount += Character.charCount(codePoint);
+                    }
+                    state = STATE_FINISHED;
+                    break;
+                case STATE_BEFORE_VS_AND_KEYCAP:
+                    if (Emoji.isKeycapBase(codePoint)) {
+                        deleteCharCount += lastSeenVSCharCount + Character.charCount(codePoint);
+                    }
+                    state = STATE_FINISHED;
+                    break;
+                case STATE_BEFORE_EMOJI_MODIFIER:
+                    if (isVariationSelector(codePoint)) {
+                        lastSeenVSCharCount = Character.charCount(codePoint);
+                        state = STATE_BEFORE_VS_AND_EMOJI_MODIFIER;
+                        break;
+                    } else if (Emoji.isEmojiModifierBase(codePoint)) {
+                        deleteCharCount += Character.charCount(codePoint);
+                    }
+                    state = STATE_FINISHED;
+                    break;
+                case STATE_BEFORE_VS_AND_EMOJI_MODIFIER:
+                    if (Emoji.isEmojiModifierBase(codePoint)) {
+                        deleteCharCount += lastSeenVSCharCount + Character.charCount(codePoint);
+                    }
+                    state = STATE_FINISHED;
+                    break;
+                case STATE_BEFORE_VS:
+                    if (Emoji.isZwjEmoji(codePoint)) {
+                        deleteCharCount += Character.charCount(codePoint);
+                        state = STATE_BEFORE_ZWJ_EMOJI;
+                        break;
+                    }
+
+                    if (!isVariationSelector(codePoint) &&
+                            UCharacter.getCombiningClass(codePoint) == 0) {
+                        deleteCharCount += Character.charCount(codePoint);
+                    }
+                    state = STATE_FINISHED;
+                    break;
+                case STATE_BEFORE_ZWJ_EMOJI:
+                    if (codePoint == Emoji.ZERO_WIDTH_JOINER) {
+                        state = STATE_BEFORE_ZWJ;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                case STATE_BEFORE_ZWJ:
+                    if (Emoji.isZwjEmoji(codePoint)) {
+                        deleteCharCount += Character.charCount(codePoint) + 1;  // +1 for ZWJ.
+                        state = STATE_BEFORE_ZWJ_EMOJI;
+                    } else if (isVariationSelector(codePoint)) {
+                        lastSeenVSCharCount = Character.charCount(codePoint);
+                        state = STATE_BEFORE_VS_AND_ZWJ;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                case STATE_BEFORE_VS_AND_ZWJ:
+                    if (Emoji.isZwjEmoji(codePoint)) {
+                        // +1 for ZWJ.
+                        deleteCharCount += lastSeenVSCharCount + 1 + Character.charCount(codePoint);
+                        lastSeenVSCharCount = 0;
+                        state = STATE_BEFORE_ZWJ_EMOJI;
+                    } else {
+                        state = STATE_FINISHED;
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("state " + state + " is unknown");
+            }
+        } while (tmpOffset > 0 && state != STATE_FINISHED);
+
+        return adjustReplacementSpan(text, offset - deleteCharCount, true /* move to the start */);
+    }
+
+    // Returns the end offset to be deleted by a forward delete key from the given offset.
+    private static int getOffsetForForwardDeleteKey(CharSequence text, int offset) {
+        final int len = text.length();
+
+        if (offset >= len - 1) {
+            return len;
+        }
+
+        int codePoint = Character.codePointAt(text, offset);
+        offset += Character.charCount(codePoint);
+        if (offset == len) {
+            return len;
+        }
+
+        // TODO: Handle emoji, combining chars, etc.
+
+        return adjustReplacementSpan(text, offset, false /* move to the end */);
+    }
+
     private boolean backspaceOrForwardDelete(View view, Editable content, int keyCode,
             KeyEvent event, boolean isForwardDelete) {
         // Ensure the key event does not have modifiers except ALT or SHIFT or CTRL.
@@ -98,9 +311,9 @@
         final int start = Selection.getSelectionEnd(content);
         final int end;
         if (isForwardDelete) {
-            end = TextUtils.getOffsetAfter(content, start);
+            end = getOffsetForForwardDeleteKey(content, start);
         } else {
-            end = TextUtils.getOffsetBefore(content, start);
+            end = getOffsetForBackspaceKey(content, start);
         }
         if (start != end) {
             content.delete(Math.min(start, end), Math.max(start, end));
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index b2e8d33..627183f 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -16,8 +16,6 @@
 
 package android.transition;
 
-import com.android.internal.R;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -28,6 +26,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import com.android.internal.R;
+
 /**
  * This transition tracks changes to the visibility of target views in the
  * start and end scenes and fades views in or out when they become visible
@@ -144,12 +144,9 @@
             Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = " +
                     startView + ", " + view);
         }
-        float startAlpha = 0;
-        if (startValues != null) {
-            startAlpha = (Float) startValues.values.get(PROPNAME_TRANSITION_ALPHA);
-            if (startAlpha == 1) {
-                startAlpha = 0;
-            }
+        float startAlpha = getStartAlpha(startValues, 0);
+        if (startAlpha == 1) {
+            startAlpha = 0;
         }
         return createAnimation(view, startAlpha, 1);
     }
@@ -157,13 +154,21 @@
     @Override
     public Animator onDisappear(ViewGroup sceneRoot, final View view, TransitionValues startValues,
             TransitionValues endValues) {
-        float startAlpha = 1;
-        if (startValues != null) {
-            startAlpha = (Float) startValues.values.get(PROPNAME_TRANSITION_ALPHA);
-        }
+        float startAlpha = getStartAlpha(startValues, 1);
         return createAnimation(view, startAlpha, 0);
     }
 
+    private static float getStartAlpha(TransitionValues startValues, float fallbackValue) {
+        float startAlpha = fallbackValue;
+        if (startValues != null) {
+            Float startAlphaFloat = (Float) startValues.values.get(PROPNAME_TRANSITION_ALPHA);
+            if (startAlphaFloat != null) {
+                startAlpha = startAlphaFloat;
+            }
+        }
+        return startAlpha;
+    }
+
     private static class FadeAnimatorListener extends AnimatorListenerAdapter {
         private final View mView;
         private boolean mLayerTypeChanged = false;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 48614c0..4afa9fe 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -2191,9 +2191,6 @@
         return mNameOverrides;
     }
 
-    /** @hide */
-    public void forceVisibility(int visibility, boolean isStartValue) {}
-
     @Override
     public String toString() {
         return toString("");
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 09d2c69..583dc0f 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -46,7 +46,7 @@
  * transition on the affected view targets:</p>
  * <pre>
  *     &lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
- *             android:ordering="sequential"&gt;
+ *             android:transitionOrdering="sequential"&gt;
  *         &lt;fade/&gt;
  *         &lt;changeBounds/&gt;
  *     &lt;/transitionSet&gt;
@@ -318,15 +318,6 @@
         }
     }
 
-    /** @hide */
-    @Override
-    public void forceVisibility(int visibility, boolean isStartValue) {
-        int numTransitions = mTransitions.size();
-        for (int i = 0; i < numTransitions; i++) {
-            mTransitions.get(i).forceVisibility(visibility, isStartValue);
-        }
-    }
-
     /**
      * Removes the specified child transition from this set.
      *
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index eb95a02..4eaab37 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -85,9 +85,6 @@
 
     private int mMode = MODE_IN | MODE_OUT;
 
-    private int mForcedStartVisibility = -1;
-    private int mForcedEndVisibility = -1;
-
     public Visibility() {}
 
     public Visibility(Context context, AttributeSet attrs) {
@@ -132,13 +129,8 @@
         return sTransitionProperties;
     }
 
-    private void captureValues(TransitionValues transitionValues, int forcedVisibility) {
-        int visibility;
-        if (forcedVisibility != -1) {
-            visibility = forcedVisibility;
-        } else {
-            visibility = transitionValues.view.getVisibility();
-        }
+    private void captureValues(TransitionValues transitionValues) {
+        int visibility = transitionValues.view.getVisibility();
         transitionValues.values.put(PROPNAME_VISIBILITY, visibility);
         transitionValues.values.put(PROPNAME_PARENT, transitionValues.view.getParent());
         int[] loc = new int[2];
@@ -148,22 +140,12 @@
 
     @Override
     public void captureStartValues(TransitionValues transitionValues) {
-        captureValues(transitionValues, mForcedStartVisibility);
+        captureValues(transitionValues);
     }
 
     @Override
     public void captureEndValues(TransitionValues transitionValues) {
-        captureValues(transitionValues, mForcedEndVisibility);
-    }
-
-    /** @hide */
-    @Override
-    public void forceVisibility(int visibility, boolean isStartValue) {
-        if (isStartValue) {
-            mForcedStartVisibility = visibility;
-        } else {
-            mForcedEndVisibility = visibility;
-        }
+        captureValues(transitionValues);
     }
 
     /**
@@ -298,12 +280,6 @@
                 return null;
             }
         }
-        final boolean isForcedVisibility = mForcedStartVisibility != -1 ||
-                mForcedEndVisibility != -1;
-        if (isForcedVisibility) {
-            // Make sure that we reverse the effect of onDisappear's setTransitionAlpha(0)
-            endValues.view.setTransitionAlpha(1);
-        }
         return onAppear(sceneRoot, endValues.view, startValues, endValues);
     }
 
@@ -447,21 +423,16 @@
         }
 
         if (viewToKeep != null) {
-            int originalVisibility = -1;
-            final boolean isForcedVisibility = mForcedStartVisibility != -1 ||
-                    mForcedEndVisibility != -1;
-            if (!isForcedVisibility) {
-                originalVisibility = viewToKeep.getVisibility();
-                viewToKeep.setTransitionVisibility(View.VISIBLE);
-            }
+            int originalVisibility = viewToKeep.getVisibility();
+            viewToKeep.setTransitionVisibility(View.VISIBLE);
             Animator animator = onDisappear(sceneRoot, viewToKeep, startValues, endValues);
             if (animator != null) {
                 DisappearListener disappearListener = new DisappearListener(viewToKeep,
-                        finalVisibility, isForcedVisibility);
+                        finalVisibility);
                 animator.addListener(disappearListener);
                 animator.addPauseListener(disappearListener);
                 addListener(disappearListener);
-            } else if (!isForcedVisibility) {
+            } else {
                 viewToKeep.setTransitionVisibility(originalVisibility);
             }
             return animator;
@@ -509,18 +480,15 @@
 
     private static class DisappearListener
             extends TransitionListenerAdapter implements AnimatorListener, AnimatorPauseListener {
-        private final boolean mIsForcedVisibility;
         private final View mView;
         private final int mFinalVisibility;
         private final ViewGroup mParent;
 
         private boolean mLayoutSuppressed;
-        private boolean mFinalVisibilitySet = false;
         boolean mCanceled = false;
 
-        public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) {
+        public DisappearListener(View view, int finalVisibility) {
             this.mView = view;
-            this.mIsForcedVisibility = isForcedVisibility;
             this.mFinalVisibility = finalVisibility;
             this.mParent = (ViewGroup) view.getParent();
             // Prevent a layout from including mView in its calculation.
@@ -529,14 +497,14 @@
 
         @Override
         public void onAnimationPause(Animator animation) {
-            if (!mCanceled && !mIsForcedVisibility) {
+            if (!mCanceled) {
                 mView.setTransitionVisibility(mFinalVisibility);
             }
         }
 
         @Override
         public void onAnimationResume(Animator animation) {
-            if (!mCanceled && !mIsForcedVisibility) {
+            if (!mCanceled) {
                 mView.setTransitionVisibility(View.VISIBLE);
             }
         }
@@ -576,15 +544,10 @@
 
         private void hideViewWhenNotCanceled() {
             if (!mCanceled) {
-                if (mIsForcedVisibility) {
-                    mView.setTransitionAlpha(0);
-                } else if (!mFinalVisibilitySet) {
-                    // Recreate the parent's display list in case it includes mView.
-                    mView.setTransitionVisibility(mFinalVisibility);
-                    if (mParent != null) {
-                        mParent.invalidate();
-                    }
-                    mFinalVisibilitySet = true;
+                // Recreate the parent's display list in case it includes mView.
+                mView.setTransitionVisibility(mFinalVisibility);
+                if (mParent != null) {
+                    mParent.invalidate();
                 }
             }
             // Layout is allowed now that the View is in its final state
@@ -592,7 +555,7 @@
         }
 
         private void suppressLayout(boolean suppress) {
-            if (mLayoutSuppressed != suppress && mParent != null && !mIsForcedVisibility) {
+            if (mLayoutSuppressed != suppress && mParent != null) {
                 mLayoutSuppressed = suppress;
                 mParent.suppressLayout(suppress);
             }
diff --git a/core/java/android/util/BackupUtils.java b/core/java/android/util/BackupUtils.java
new file mode 100644
index 0000000..474ceda
--- /dev/null
+++ b/core/java/android/util/BackupUtils.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Utility methods for Backup/Restore
+ * @hide
+ */
+public class BackupUtils {
+
+    public static final int NULL = 0;
+    public static final int NOT_NULL = 1;
+
+    /**
+     * Thrown when there is a backup version mismatch
+     * between the data received and what the system can handle
+     */
+    public static class BadVersionException extends Exception {
+        public BadVersionException(String message) {
+            super(message);
+        }
+    }
+
+    public static String readString(DataInputStream in) throws IOException {
+        return (in.readByte() == NOT_NULL) ? in.readUTF() : null;
+    }
+
+    public static void writeString(DataOutputStream out, String val) throws IOException {
+        if (val != null) {
+            out.writeByte(NOT_NULL);
+            out.writeUTF(val);
+        } else {
+            out.writeByte(NULL);
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
new file mode 100644
index 0000000..8e66f86
--- /dev/null
+++ b/core/java/android/view/FrameMetrics.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.IntDef;
+import android.view.Window;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Class containing timing data for various milestones in a frame
+ * lifecycle reported by the rendering subsystem.
+ * <p>
+ * Supported metrics can be queried via their corresponding identifier.
+ * </p>
+ */
+public final class FrameMetrics {
+
+    /**
+     * Metric identifier for unknown delay.
+     * <p>
+     * Represents the number of nanoseconds elapsed waiting for the
+     * UI thread to become responsive and process the frame. This
+     * should be 0 most of the time.
+     * </p>
+     */
+    public static final int UNKNOWN_DELAY_DURATION = 0;
+
+    /**
+     * Metric identifier for input handling duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed issuing
+     * input handling callbacks.
+     * </p>
+     */
+    public static final int INPUT_HANDLING_DURATION = 1;
+
+    /**
+     * Metric identifier for animation callback duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed issuing
+     * animation callbacks.
+     * </p>
+     */
+    public static final int ANIMATION_DURATION = 2;
+
+    /**
+     * Metric identifier for layout/measure duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed measuring
+     * and laying out the invalidated pieces of the view hierarchy.
+     * </p>
+     */
+    public static final int LAYOUT_MEASURE_DURATION = 3;
+    /**
+     * Metric identifier for draw duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed computing
+     * DisplayLists for transformations applied to the view
+     * hierarchy.
+     * </p>
+     */
+    public static final int DRAW_DURATION = 4;
+
+    /**
+     * Metric identifier for sync duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed
+     * synchronizing the computed display lists with the render
+     * thread.
+     * </p>
+     */
+    public static final int SYNC_DURATION = 5;
+
+    /**
+     * Metric identifier for command issue duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed
+     * issuing draw commands to the GPU.
+     * </p>
+     */
+    public static final int COMMAND_ISSUE_DURATION = 6;
+
+    /**
+     * Metric identifier for swap buffers duration.
+     * <p>
+     * Represents the number of nanoseconds elapsed issuing
+     * the frame buffer for this frame to the display
+     * subsystem.
+     * </p>
+     */
+    public static final int SWAP_BUFFERS_DURATION = 7;
+
+    /**
+     * Metric identifier for total frame duration.
+     * <p>
+     * Represents the total time in nanoseconds this frame took to render
+     * and be issued to the display subsystem.
+     * </p>
+     * <p>
+     * Equal to the sum of the values of all other time-valued metric
+     * identifiers.
+     * </p>
+     */
+    public static final int TOTAL_DURATION = 8;
+
+    /**
+     * Metric identifier for a boolean value determining whether this frame was
+     * the first to draw in a new Window layout.
+     * <p>
+     * {@link #getMetric(int)} will return 0 for false, 1 for true.
+     * </p>
+     * <p>
+     * First draw frames are expected to be slow and should usually be exempt
+     * from display jank calculations as they do not cause skips in animations
+     * and are usually hidden by window animations or other tricks.
+     * </p>
+     */
+    public static final int FIRST_DRAW_FRAME = 9;
+
+    private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
+
+    /**
+     * Identifiers for metrics available for each frame.
+     *
+     * {@see {@link #getMetric(int)}}
+     * @hide
+     */
+    @IntDef({
+            UNKNOWN_DELAY_DURATION,
+            INPUT_HANDLING_DURATION,
+            ANIMATION_DURATION,
+            LAYOUT_MEASURE_DURATION,
+            DRAW_DURATION,
+            SYNC_DURATION,
+            COMMAND_ISSUE_DURATION,
+            SWAP_BUFFERS_DURATION,
+            TOTAL_DURATION,
+            FIRST_DRAW_FRAME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Metric {}
+
+    /**
+     * Timestamp indices for frame milestones.
+     *
+     * May change from release to release.
+     *
+     * Must be kept in sync with frameworks/base/libs/hwui/FrameInfo.h.
+     *
+     * @hide
+     */
+    @IntDef ({
+            Index.FLAGS,
+            Index.INTENDED_VSYNC,
+            Index.VSYNC,
+            Index.OLDEST_INPUT_EVENT,
+            Index.NEWEST_INPUT_EVENT,
+            Index.HANDLE_INPUT_START,
+            Index.ANIMATION_START,
+            Index.PERFORM_TRAVERSALS_START,
+            Index.DRAW_START,
+            Index.SYNC_QUEUED,
+            Index.SYNC_START,
+            Index.ISSUE_DRAW_COMMANDS_START,
+            Index.SWAP_BUFFERS,
+            Index.FRAME_COMPLETED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface Index {
+        int FLAGS = 0;
+        int INTENDED_VSYNC = 1;
+        int VSYNC = 2;
+        int OLDEST_INPUT_EVENT = 3;
+        int NEWEST_INPUT_EVENT = 4;
+        int HANDLE_INPUT_START = 5;
+        int ANIMATION_START = 6;
+        int PERFORM_TRAVERSALS_START = 7;
+        int DRAW_START = 8;
+        int SYNC_QUEUED = 9;
+        int SYNC_START = 10;
+        int ISSUE_DRAW_COMMANDS_START = 11;
+        int SWAP_BUFFERS = 12;
+        int FRAME_COMPLETED = 13;
+
+        int FRAME_STATS_COUNT = 14; // must always be last
+    }
+
+    /*
+     * Bucket endpoints for each Metric defined above.
+     *
+     * Each defined metric *must* have a corresponding entry
+     * in this list.
+     */
+    private static final int[] DURATIONS = new int[] {
+        // UNKNOWN_DELAY
+        Index.INTENDED_VSYNC, Index.HANDLE_INPUT_START,
+        // INPUT_HANDLING
+        Index.HANDLE_INPUT_START, Index.ANIMATION_START,
+        // ANIMATION
+        Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START,
+        // LAYOUT_MEASURE
+        Index.PERFORM_TRAVERSALS_START, Index.DRAW_START,
+        // DRAW
+        Index.DRAW_START, Index.SYNC_QUEUED,
+        // SYNC
+        Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START,
+        // COMMAND_ISSUE
+        Index.ISSUE_DRAW_COMMANDS_START, Index.SWAP_BUFFERS,
+        // SWAP_BUFFERS
+        Index.SWAP_BUFFERS, Index.FRAME_COMPLETED,
+        // TOTAL_DURATION
+        Index.INTENDED_VSYNC, Index.FRAME_COMPLETED,
+    };
+
+    /* package */ final long[] mTimingData;
+
+    /**
+     * Constructs a FrameMetrics object as a copy.
+     * <p>
+     * Use this method to copy out metrics reported by
+     * {@link Window.FrameMetricsListener#onMetricsAvailable(Window, FrameMetrics, int)}
+     * </p>
+     * @param other the FrameMetrics object to copy.
+     */
+    public FrameMetrics(FrameMetrics other) {
+        mTimingData = new long[Index.FRAME_STATS_COUNT];
+        System.arraycopy(other.mTimingData, 0, mTimingData, 0, mTimingData.length);
+    }
+
+    /**
+     * @hide
+     */
+    FrameMetrics() {
+        mTimingData = new long[Index.FRAME_STATS_COUNT];
+    }
+
+    /**
+     * Retrieves the value associated with Metric identifier {@code id}
+     * for this frame.
+     * <p>
+     * Boolean metrics are represented in [0,1], with 0 corresponding to
+     * false, and 1 corresponding to true.
+     * </p>
+     * @param id the metric to retrieve
+     * @return the value of the metric or -1 if it is not available.
+     */
+    public long getMetric(@Metric int id) {
+        if (id < UNKNOWN_DELAY_DURATION || id > FIRST_DRAW_FRAME) {
+            return -1;
+        }
+
+        if (mTimingData == null) {
+            return -1;
+        }
+
+        if (id == FIRST_DRAW_FRAME) {
+            return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
+        }
+
+        int durationsIdx = 2 * id;
+        return mTimingData[DURATIONS[durationsIdx + 1]]
+                - mTimingData[DURATIONS[durationsIdx]];
+    }
+}
+
diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java
new file mode 100644
index 0000000..f38f8b7
--- /dev/null
+++ b/core/java/android/view/FrameMetricsObserver.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.annotation.NonNull;
+import android.util.Log;
+import android.os.Looper;
+import android.os.MessageQueue;
+
+import com.android.internal.util.VirtualRefBasePtr;
+
+import java.lang.NullPointerException;
+import java.lang.ref.WeakReference;
+import java.lang.SuppressWarnings;
+
+/**
+ * Provides streaming access to frame stats information from the rendering
+ * subsystem to apps.
+ *
+ * @hide
+ */
+public class FrameMetricsObserver {
+    private MessageQueue mMessageQueue;
+
+    private WeakReference<Window> mWindow;
+
+    private FrameMetrics mFrameMetrics;
+
+    /* package */ Window.FrameMetricsListener mListener;
+    /* package */ VirtualRefBasePtr mNative;
+
+    /**
+     * Creates a FrameMetricsObserver
+     *
+     * @param looper the looper to use when invoking callbacks
+     */
+    FrameMetricsObserver(@NonNull Window window, @NonNull Looper looper,
+            @NonNull Window.FrameMetricsListener listener) {
+        if (looper == null) {
+            throw new NullPointerException("looper cannot be null");
+        }
+
+        mMessageQueue = looper.getQueue();
+        if (mMessageQueue == null) {
+            throw new IllegalStateException("invalid looper, null message queue\n");
+        }
+
+        mFrameMetrics = new FrameMetrics();
+        mWindow = new WeakReference<>(window);
+        mListener = listener;
+    }
+
+    // Called by native on the provided Handler
+    @SuppressWarnings("unused")
+    private void notifyDataAvailable(int dropCount) {
+        final Window window = mWindow.get();
+        if (window != null) {
+            mListener.onMetricsAvailable(window, mFrameMetrics, dropCount);
+        }
+    }
+}
diff --git a/core/java/android/view/FrameStatsObserver.java b/core/java/android/view/FrameStatsObserver.java
deleted file mode 100644
index 0add607..0000000
--- a/core/java/android/view/FrameStatsObserver.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.annotation.NonNull;
-import android.util.Log;
-import android.os.Looper;
-import android.os.MessageQueue;
-
-import com.android.internal.util.VirtualRefBasePtr;
-
-import java.lang.NullPointerException;
-import java.lang.ref.WeakReference;
-import java.lang.SuppressWarnings;
-
-/**
- * Provides streaming access to frame stats information from the rendering
- * subsystem to apps.
- *
- * @hide
- */
-public abstract class FrameStatsObserver {
-    private static final String TAG = "FrameStatsObserver";
-
-    private MessageQueue mMessageQueue;
-    private long[] mBuffer;
-
-    private FrameStats mFrameStats;
-
-    /* package */ ThreadedRenderer mRenderer;
-    /* package */ VirtualRefBasePtr mNative;
-
-    /**
-     * Containing class for frame statistics reported
-     * by the rendering subsystem.
-     */
-    public static class FrameStats {
-        /**
-         * Precise timing data for various milestones in a frame
-         * lifecycle.
-         *
-         * This data is exactly the same as what is returned by
-         * `adb shell dumpsys gfxinfo <PACKAGE_NAME> framestats`
-         *
-         * The fields reported may change from release to release.
-         *
-         * @see {@link http://developer.android.com/training/testing/performance.html}
-         * for a description of the fields present.
-         */
-        public long[] mTimingData;
-    }
-
-    /**
-     * Creates a FrameStatsObserver
-     *
-     * @param looper the looper to use when invoking callbacks
-     */
-    public FrameStatsObserver(@NonNull Looper looper) {
-        if (looper == null) {
-            throw new NullPointerException("looper cannot be null");
-        }
-
-        mMessageQueue = looper.getQueue();
-        if (mMessageQueue == null) {
-            throw new IllegalStateException("invalid looper, null message queue\n");
-        }
-
-        mFrameStats = new FrameStats();
-    }
-
-    /**
-     * Called on provided looper when frame stats data is available
-     * for the previous frame.
-     *
-     * Clients of this class must do as little work as possible within
-     * this callback, as the buffer is shared between the producer and consumer.
-     *
-     * If the consumer is still executing within this method when there is new
-     * data available that data will be dropped. The producer cannot
-     * wait on the consumer.
-     *
-     * @param data the newly available data
-     */
-    public abstract void onDataAvailable(FrameStats data);
-
-    /**
-     * Returns the number of reports dropped as a result of a slow
-     * consumer.
-     */
-    public long getDroppedReportCount() {
-        if (mRenderer == null) {
-            return 0;
-        }
-
-        return mRenderer.getDroppedFrameReportCount();
-    }
-
-    public boolean isRegistered() {
-        return mRenderer != null && mNative != null;
-    }
-
-    // === called by native === //
-    @SuppressWarnings("unused")
-    private void notifyDataAvailable() {
-        mFrameStats.mTimingData = mBuffer;
-        onDataAvailable(mFrameStats);
-    }
-}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 1740f07..5b9930b 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -166,6 +166,7 @@
             in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
             int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
     void setAppVisibility(IBinder token, boolean visible);
+    void notifyAppStopped(IBinder token);
     void startAppFreezingScreen(IBinder token, int configChanges);
     void stopAppFreezingScreen(IBinder token, boolean force);
     void removeAppToken(IBinder token);
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 1703ed1..6a2cc80 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -260,4 +260,6 @@
      * Returns true if the move started successfully; false otherwise.
      */
     boolean startMovingTask(IWindow window, float startX, float startY);
+
+    void updatePointerIcon(IWindow window);
 }
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 7017ff5..a4cb703 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -775,6 +775,10 @@
         mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
     }
 
+    public boolean isAttached() {
+        return mOwningView != null && mOwningView.mAttachInfo != null;
+    }
+
     public void addAnimator(AnimatedVectorDrawable.VectorDrawableAnimator animatorSet) {
         if (mOwningView == null || mOwningView.mAttachInfo == null) {
             throw new IllegalStateException("Cannot start this animator on a detached view!");
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index a296051..152dd66 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -224,7 +224,7 @@
         mParent.requestTransparentRegion(this);
         mSession = getWindowSession();
         mLayout.token = getWindowToken();
-        mLayout.setTitle("SurfaceView");
+        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
         mViewVisibility = getVisibility() == VISIBLE;
 
         if (!mGlobalListenersAdded) {
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 8b06ecf..ca41d78 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -354,8 +354,6 @@
     private boolean mEnabled;
     private boolean mRequested = true;
 
-    private HashSet<FrameStatsObserver> mFrameStatsObservers;
-
     ThreadedRenderer(Context context, boolean translucent) {
         final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
         mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
@@ -964,29 +962,14 @@
         }
     }
 
-    void addFrameStatsObserver(FrameStatsObserver fso) {
-        if (mFrameStatsObservers == null) {
-            mFrameStatsObservers = new HashSet<>();
-        }
-
-        long nativeFso = nAddFrameStatsObserver(mNativeProxy, fso);
-        fso.mRenderer = this;
-        fso.mNative = new VirtualRefBasePtr(nativeFso);
-        mFrameStatsObservers.add(fso);
+    void addFrameMetricsObserver(FrameMetricsObserver observer) {
+        long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
+        observer.mNative = new VirtualRefBasePtr(nativeObserver);
     }
 
-    void removeFrameStatsObserver(FrameStatsObserver fso) {
-        if (!mFrameStatsObservers.remove(fso)) {
-            throw new IllegalArgumentException("attempt to remove FrameStatsObserver that was never added");
-        }
-
-        nRemoveFrameStatsObserver(mNativeProxy, fso.mNative.get());
-        fso.mRenderer = null;
-        fso.mNative = null;
-    }
-
-    long getDroppedFrameReportCount() {
-        return nGetDroppedFrameReportCount(mNativeProxy);
+    void removeFrameMetricsObserver(FrameMetricsObserver observer) {
+        nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
+        observer.mNative = null;
     }
 
     static native void setupShadersDiskCache(String cacheFile);
@@ -1044,7 +1027,6 @@
     private static native void nSetContentDrawBounds(long nativeProxy, int left,
              int top, int right, int bottom);
 
-    private static native long nAddFrameStatsObserver(long nativeProxy, FrameStatsObserver fso);
-    private static native void nRemoveFrameStatsObserver(long nativeProxy, long nativeFso);
-    private static native long nGetDroppedFrameReportCount(long nativeProxy);
+    private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
+    private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 127157b..9e9ad67 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3703,9 +3703,9 @@
     private ViewPropertyAnimator mAnimator = null;
 
     /**
-     * List of FrameStatsObservers pending registration when mAttachInfo is null.
+     * List of registered FrameMetricsObservers.
      */
-    private ArrayList<FrameStatsObserver> mPendingFrameStatsObservers;
+    private ArrayList<FrameMetricsObserver> mFrameMetricsObservers;
 
     /**
      * Flag indicating that a drag can cross window boundaries.  When
@@ -5479,19 +5479,29 @@
      *
      * @hide
      */
-    public void addFrameStatsObserver(FrameStatsObserver fso) {
+    public void addFrameMetricsListener(Window window, Window.FrameMetricsListener listener,
+            Handler handler) {
         if (mAttachInfo != null) {
             if (mAttachInfo.mHardwareRenderer != null) {
-                mAttachInfo.mHardwareRenderer.addFrameStatsObserver(fso);
+                if (mFrameMetricsObservers == null) {
+                    mFrameMetricsObservers = new ArrayList<>();
+                }
+
+                FrameMetricsObserver fmo = new FrameMetricsObserver(window,
+                        handler.getLooper(), listener);
+                mFrameMetricsObservers.add(fmo);
+                mAttachInfo.mHardwareRenderer.addFrameMetricsObserver(fmo);
             } else {
                 Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
             }
         } else {
-            if (mPendingFrameStatsObservers == null) {
-                mPendingFrameStatsObservers = new ArrayList<>();
+            if (mFrameMetricsObservers == null) {
+                mFrameMetricsObservers = new ArrayList<>();
             }
 
-            mPendingFrameStatsObservers.add(fso);
+            FrameMetricsObserver fmo = new FrameMetricsObserver(window,
+                    handler.getLooper(), listener);
+            mFrameMetricsObservers.add(fmo);
         }
     }
 
@@ -5500,32 +5510,45 @@
      *
      * @hide
      */
-    public void removeFrameStatsObserver(FrameStatsObserver fso) {
+    public void removeFrameMetricsListener(Window.FrameMetricsListener listener) {
         ThreadedRenderer renderer = getHardwareRenderer();
-
-        if (mPendingFrameStatsObservers != null) {
-            mPendingFrameStatsObservers.remove(fso);
+        FrameMetricsObserver fmo = findFrameMetricsObserver(listener);
+        if (fmo == null) {
+            throw new IllegalArgumentException("attempt to remove FrameMetricsListener that was never added");
         }
 
-        if (renderer != null) {
-            renderer.removeFrameStatsObserver(fso);
+        if (mFrameMetricsObservers != null) {
+            mFrameMetricsObservers.remove(fmo);
+            if (renderer != null) {
+                renderer.removeFrameMetricsObserver(fmo);
+            }
         }
     }
 
-    private void registerPendingFrameStatsObservers() {
-        if (mPendingFrameStatsObservers != null) {
+    private void registerPendingFrameMetricsObservers() {
+        if (mFrameMetricsObservers != null) {
             ThreadedRenderer renderer = getHardwareRenderer();
             if (renderer != null) {
-                for (FrameStatsObserver fso : mPendingFrameStatsObservers) {
-                    renderer.addFrameStatsObserver(fso);
+                for (FrameMetricsObserver fmo : mFrameMetricsObservers) {
+                    renderer.addFrameMetricsObserver(fmo);
                 }
             } else {
                 Log.w(VIEW_LOG_TAG, "View not hardware-accelerated. Unable to observe frame stats");
             }
-            mPendingFrameStatsObservers = null;
         }
     }
 
+    private FrameMetricsObserver findFrameMetricsObserver(Window.FrameMetricsListener listener) {
+        for (int i = 0; i < mFrameMetricsObservers.size(); i++) {
+            FrameMetricsObserver observer = mFrameMetricsObservers.get(i);
+            if (observer.mListener == listener) {
+                return observer;
+            }
+        }
+
+        return null;
+    }
+
     /**
      * Call this view's OnClickListener, if it is defined.  Performs all normal
      * actions associated with clicking: reporting accessibility event, playing
@@ -6851,6 +6874,15 @@
      * @param info The info whose drawing order should be populated
      */
     private void populateAccessibilityNodeInfoDrawingOrderInParent(AccessibilityNodeInfo info) {
+        /*
+         * If the view's bounds haven't been set yet, layout has not completed. In that situation,
+         * drawing order may not be well-defined, and some Views with custom drawing order may
+         * not be initialized sufficiently to respond properly getChildDrawingOrder.
+         */
+        if ((mPrivateFlags & PFLAG_HAS_BOUNDS) == 0) {
+            info.setDrawingOrder(0);
+            return;
+        }
         int drawingOrderInParent = 1;
         // Iterate up the hierarchy if parents are not important for a11y
         View viewAtDrawingLevel = this;
@@ -10871,6 +10903,9 @@
                     return true;
                 }
             case MotionEvent.ACTION_DOWN:
+                if (mScrollCache.state == ScrollabilityCache.OFF) {
+                    return false;
+                }
                 if (isOnVerticalScrollbarThumb(x, y)) {
                     mScrollCache.mScrollBarDraggingState =
                             ScrollabilityCache.DRAGGING_VERTICAL_SCROLL_BAR;
@@ -15160,7 +15195,7 @@
             mFloatingTreeObserver = null;
         }
 
-        registerPendingFrameStatsObservers();
+        registerPendingFrameMetricsObservers();
 
         if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
             mAttachInfo.mScrollContainers.add(this);
@@ -16582,11 +16617,12 @@
         RenderNode renderNode = null;
         Bitmap cache = null;
         int layerType = getLayerType(); // TODO: signify cache state with just 'cache' local
-        if (layerType == LAYER_TYPE_SOFTWARE
-                || (!drawingWithRenderNode && layerType != LAYER_TYPE_NONE)) {
-            // If not drawing with RenderNode, treat HW layers as SW
-            layerType = LAYER_TYPE_SOFTWARE;
-            buildDrawingCache(true);
+        if (layerType == LAYER_TYPE_SOFTWARE || !drawingWithRenderNode) {
+             if (layerType != LAYER_TYPE_NONE) {
+                 // If not drawing with RenderNode, treat HW layers as SW
+                 layerType = LAYER_TYPE_SOFTWARE;
+                 buildDrawingCache(true);
+            }
             cache = getDrawingCache(true);
         }
 
@@ -21548,6 +21584,13 @@
      */
     public void setPointerIcon(PointerIcon pointerIcon) {
         mPointerIcon = pointerIcon;
+        if (mAttachInfo == null) {
+            return;
+        }
+        try {
+            mAttachInfo.mSession.updatePointerIcon(mAttachInfo.mWindow);
+        } catch (RemoteException e) {
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 96853e0..6dc5ccc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1606,10 +1606,6 @@
                         frame.height() < desiredWindowHeight && frame.height() != mHeight));
         windowShouldResize |= mDragResizing && mResizeMode == RESIZE_MODE_FREEFORM;
 
-        // If the backdrop frame doesn't equal to a frame, we are starting a resize operation, so
-        // force it to be resized.
-        windowShouldResize |= !mPendingBackDropFrame.equals(mWinFrame);
-
         // If the activity was just relaunched, it might have unfrozen the task bounds (while
         // relaunching), so we need to force a call into window manager to pick up the latest
         // bounds.
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index c68a740..9f05990 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -34,6 +34,7 @@
 import android.media.session.MediaController;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -604,6 +605,34 @@
         void onRestrictedCaptionAreaChanged(Rect rect);
     }
 
+    /**
+     * Callback for clients that want frame timing information for each
+     * frame rendered by the Window.
+     */
+    public interface FrameMetricsListener {
+        /**
+         * Called when information is available for the previously rendered frame.
+         *
+         * Reports can be dropped if this callback takes too
+         * long to execute, as the report producer cannot wait for the consumer to
+         * complete.
+         *
+         * It is highly recommended that clients copy the passed in FrameMetrics
+         * via {@link FrameMetrics#FrameMetrics(FrameMetrics)} within this method and defer
+         * additional computation or storage to another thread to avoid unnecessarily
+         * dropping reports.
+         *
+         * @param window The {@link Window} on which the frame was displayed.
+         * @param frameMetrics the available metrics. This object is reused on every call
+         * and thus <strong>this reference is not valid outside the scope of this method</strong>.
+         * @param dropCountSinceLastInvocation the number of reports dropped since the last time
+         * this callback was invoked.
+         */
+        void onMetricsAvailable(Window window, FrameMetrics frameMetrics,
+                int dropCountSinceLastInvocation);
+    }
+
+
     public Window(Context context) {
         mContext = context;
         mFeatures = mLocalFeatures = getDefaultFeatures(context);
@@ -798,33 +827,28 @@
      * Set an observer to collect frame stats for each frame rendererd in this window.
      *
      * Must be in hardware rendering mode.
-     * @hide
      */
-    public final void addFrameStatsObserver(@NonNull FrameStatsObserver fso) {
+    public final void addFrameMetricsListener(@NonNull FrameMetricsListener listener,
+            Handler handler) {
         final View decorView = getDecorView();
         if (decorView == null) {
             throw new IllegalStateException("can't observe a Window without an attached view");
         }
 
-        if (fso == null) {
-            throw new NullPointerException("FrameStatsObserver cannot be null");
+        if (listener == null) {
+            throw new NullPointerException("listener cannot be null");
         }
 
-        if (fso.isRegistered()) {
-            throw new IllegalStateException("FrameStatsObserver already registered on a Window.");
-        }
-
-        decorView.addFrameStatsObserver(fso);
+        decorView.addFrameMetricsListener(this, listener, handler);
     }
 
     /**
      * Remove observer and stop listening to frame stats for this window.
-     * @hide
      */
-    public final void removeFrameStatsObserver(FrameStatsObserver fso) {
+    public final void removeFrameMetricsListener(FrameMetricsListener listener) {
         final View decorView = getDecorView();
         if (decorView != null) {
-            getDecorView().removeFrameStatsObserver(fso);
+            getDecorView().removeFrameMetricsListener(listener);
         }
     }
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 0c5a5fc..18dfdfd 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1724,7 +1724,7 @@
         }
 
         public final CharSequence getTitle() {
-            return mTitle;
+            return mTitle != null ? mTitle : "";
         }
 
         /** @hide */
@@ -1950,7 +1950,8 @@
                 // already have one.
                 packageName = o.packageName;
             }
-            if (!mTitle.equals(o.mTitle)) {
+            if (o.mTitle != null) {
+                // NOTE: mTitle only copied if the originator set one.
                 mTitle = o.mTitle;
                 changes |= TITLE_CHANGED;
             }
@@ -2194,7 +2195,7 @@
             }
         }
 
-        private CharSequence mTitle = "";
+        private CharSequence mTitle = null;
 
         /** @hide */
         @Override
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 6e38b32..609c471 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.app.ActivityManager.StackId;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.CompatibilityInfo;
@@ -388,6 +389,12 @@
          * Check whether the window is currently dimming.
          */
         public boolean isDimming();
+
+        /**
+         * @return the stack id this windows belongs to, or {@link StackId#INVALID_STACK_ID} if
+         *         not attached to any stack.
+         */
+        int getStackId();
     }
 
     /**
@@ -460,6 +467,16 @@
 
         /** Unregister a system listener for touch events */
         void unregisterPointerEventListener(PointerEventListener listener);
+
+        /**
+         * @return The content insets of the docked divider window.
+         */
+        int getDockedDividerInsetsLw();
+
+        /**
+         * Retrieves the {@param outBounds} from the stack with id {@param stackId}.
+         */
+        void getStackBounds(int stackId, Rect outBounds);
     }
 
     public interface PointerEventListener {
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 43306d0..d97f8af 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -38,7 +38,6 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
-import android.view.inputmethod.InputMethodSubtypeArray;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -122,7 +121,7 @@
      * @param context The Context in which we are parsing the input method.
      * @param service The ResolveInfo returned from the package manager about
      * this input method's component.
-     * @param additionalSubtypes additional subtypes being added to this InputMethodInfo
+     * @param additionalSubtypesMap additional subtypes being added to this InputMethodInfo
      * @hide
      */
     public InputMethodInfo(Context context, ResolveInfo service,
@@ -429,6 +428,18 @@
         }
     }
 
+    /**
+     * @return {@code true} if the {@link android.inputmethodservice.InputMethodService} is marked
+     * to be Encryption-Aware.
+     * @hide
+     */
+    public boolean isEncryptionAware() {
+        if (mService == null || mService.serviceInfo == null) {
+            return false;
+        }
+        return mService.serviceInfo.encryptionAware;
+    }
+
     public void dump(Printer pw, String prefix) {
         pw.println(prefix + "mId=" + mId
                 + " mSettingsActivityName=" + mSettingsActivityName
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 0e5034d..8318656 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -332,7 +332,9 @@
      * in memory (for the life of the application) if proceed() or cancel() is
      * called and does not call onReceivedClientCertRequest() again for the
      * same host and port pair. Webview does not store the response if ignore()
-     * is called.
+     * is called. Note that, multiple layers in chromium network stack might be
+     * caching the responses, so the behavior for ignore is only a best case
+     * effort.
      *
      * This method is called on the UI thread. During the callback, the
      * connection is suspended.
diff --git a/core/java/android/webkit/WebViewProviderInfo.java b/core/java/android/webkit/WebViewProviderInfo.java
index 3f50fe2..94e8b70 100644
--- a/core/java/android/webkit/WebViewProviderInfo.java
+++ b/core/java/android/webkit/WebViewProviderInfo.java
@@ -97,22 +97,12 @@
      */
     public boolean isEnabled() {
         try {
-            PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
-            int enabled_state = pm.getApplicationEnabledSetting(packageName);
-            switch (enabled_state) {
-                case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
-                    return true;
-                case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
-                    ApplicationInfo applicationInfo = getPackageInfo().applicationInfo;
-                    return applicationInfo.enabled;
-                default:
-                    return false;
-            }
+            // Explicitly fetch up-to-date package info here since the enabled-state of the package
+            // might have changed since we last fetched its package info.
+            updatePackageInfo();
+            return getPackageInfo().applicationInfo.enabled;
         } catch (WebViewPackageNotFoundException e) {
             return false;
-        } catch (IllegalArgumentException e) {
-            // Thrown by PackageManager.getApplicationEnabledSetting if the package does not exist
-            return false;
         }
     }
 
@@ -124,14 +114,18 @@
         return availableByDefault;
     }
 
+    private void updatePackageInfo() {
+        try {
+            PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
+            packageInfo = pm.getPackageInfo(packageName, PACKAGE_FLAGS);
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new WebViewPackageNotFoundException(e);
+        }
+    }
+
     public PackageInfo getPackageInfo() {
         if (packageInfo == null) {
-            try {
-                PackageManager pm = AppGlobals.getInitialApplication().getPackageManager();
-                packageInfo = pm.getPackageInfo(packageName, PACKAGE_FLAGS);
-            } catch (PackageManager.NameNotFoundException e) {
-                throw new WebViewPackageNotFoundException(e);
-            }
+            updatePackageInfo();
         }
         return packageInfo;
     }
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index e31bbe9..1d242d3 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -65,6 +65,11 @@
     }
 
     @Override
+    public boolean getFreezesText() {
+        return true;
+    }
+
+    @Override
     protected boolean getDefaultEditable() {
         return true;
     }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3a61fcd..1826dd8 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1851,8 +1851,7 @@
         updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset, clamped));
 
         if (mCursorCount == 2) {
-            updateCursorPosition(1, middle, bottom,
-                    layout.getSecondaryHorizontal(offset, clamped));
+            updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset, clamped));
         }
     }
 
@@ -2151,21 +2150,60 @@
         return mSelectionModifierCursorController;
     }
 
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public Drawable[] getCursorDrawable() {
+        return mCursorDrawable;
+    }
+
     private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
         if (mCursorDrawable[cursorIndex] == null)
             mCursorDrawable[cursorIndex] = mTextView.getContext().getDrawable(
                     mTextView.mCursorDrawableRes);
-
-        if (mTempRect == null) mTempRect = new Rect();
-        mCursorDrawable[cursorIndex].getPadding(mTempRect);
-        final int width = mCursorDrawable[cursorIndex].getIntrinsicWidth();
-        horizontal = Math.max(0.5f, horizontal - 0.5f);
-        final int left = (int) (horizontal) - mTempRect.left;
-        mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
+        final Drawable drawable = mCursorDrawable[cursorIndex];
+        final int left = clampCursorHorizontalPosition(drawable, horizontal);
+        final int width = drawable.getIntrinsicWidth();
+        drawable.setBounds(left, top - mTempRect.top, left + width,
                 bottom + mTempRect.bottom);
     }
 
     /**
+     * Return clamped position for the cursor. If the cursor is within the boundaries of the view,
+     * then it is offset with the left padding of the cursor drawable. If the cursor is at
+     * the beginning or the end of the text then its drawable edge is aligned with left or right of
+     * the view boundary.
+     *
+     * @param drawable   Cursor drawable.
+     * @param horizontal Horizontal position for the cursor.
+     * @return The clamped horizontal position for the cursor.
+     */
+    private final int clampCursorHorizontalPosition(final Drawable drawable, float
+            horizontal) {
+        horizontal = Math.max(0.5f, horizontal - 0.5f);
+        if (mTempRect == null) mTempRect = new Rect();
+        drawable.getPadding(mTempRect);
+        int scrollX = mTextView.getScrollX();
+        float horizontalDiff = horizontal - scrollX;
+        int viewClippedWidth = mTextView.getWidth() - mTextView.getCompoundPaddingLeft()
+                - mTextView.getCompoundPaddingRight();
+
+        final int left;
+        if (horizontalDiff >= (viewClippedWidth - 1f)) {
+            // at the rightmost position
+            final int cursorWidth = drawable.getIntrinsicWidth();
+            left = viewClippedWidth + scrollX - (cursorWidth - mTempRect.right);
+        } else if (Math.abs(horizontalDiff) <= 1f) {
+            // at the leftmost position
+            left = scrollX - mTempRect.left;
+        } else {
+            left = (int) horizontal - mTempRect.left;
+        }
+        return left;
+    }
+
+    /**
      * Called by the framework in response to a text auto-correction (such as fixing a typo using a
      * a dictionary) from the current input method, provided by it calling
      * {@link InputConnection#commitCorrection} InputConnection.commitCorrection()}. The default
@@ -3919,8 +3957,8 @@
             final Layout layout = mTextView.getLayout();
             if (layout != null && oldDrawable != mDrawable && isShowing()) {
                 // Update popup window position.
-                mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX -
-                        getHorizontalOffset() + getCursorOffset());
+                mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX -
+                        getHorizontalOffset() + getCursorOffset();
                 mPositionX += mTextView.viewportToContentHorizontalOffset();
                 mPositionHasChanged = true;
                 updatePosition(mLastParentX, mLastParentY, false, false);
@@ -4049,8 +4087,8 @@
                 final int line = layout.getLineForOffset(offset);
                 mPrevLine = line;
 
-                mPositionX = (int) (layout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX -
-                        getHorizontalOffset() + getCursorOffset());
+                mPositionX = getCursorHorizontalPosition(layout, offset) - mHotspotX -
+                        getHorizontalOffset() + getCursorOffset();
                 mPositionY = layout.getLineBottom(line);
 
                 // Take TextView's padding and scroll into account.
@@ -4062,6 +4100,17 @@
             }
         }
 
+        /**
+         * Return the clamped horizontal position for the first cursor.
+         *
+         * @param layout Text layout.
+         * @param offset Character offset for the cursor.
+         * @return The clamped horizontal position for the cursor.
+         */
+        int getCursorHorizontalPosition(Layout layout, int offset) {
+            return (int) (layout.getPrimaryHorizontal(offset) - 0.5f);
+        }
+
         public void updatePosition(int parentPositionX, int parentPositionY,
                 boolean parentPositionChanged, boolean parentScrolled) {
             positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
@@ -4300,6 +4349,16 @@
         }
 
         @Override
+        int getCursorHorizontalPosition(Layout layout, int offset) {
+            final Drawable drawable = mCursorCount > 0 ? mCursorDrawable[0] : null;
+            if (drawable != null) {
+                final float horizontal = layout.getPrimaryHorizontal(offset);
+                return clampCursorHorizontalPosition(drawable, horizontal) + mTempRect.left;
+            }
+            return super.getCursorHorizontalPosition(layout, offset);
+        }
+
+        @Override
         public boolean onTouchEvent(MotionEvent ev) {
             final boolean result = super.onTouchEvent(ev);
 
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index dee25d3..4ed175d 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1823,23 +1823,37 @@
     }
 
     /**
-     * Helper action to set layout margin on a View.
+     * Helper action to set layout params on a View.
      */
-    private class ViewMarginEndAction extends Action {
-        public ViewMarginEndAction(int viewId, int end) {
+    private class LayoutParamAction extends Action {
+
+        /** Set marginEnd */
+        public static final int LAYOUT_MARGIN_END = 1;
+        /** Set width */
+        public static final int LAYOUT_WIDTH = 2;
+
+        /**
+         * @param viewId ID of the view alter
+         * @param property which layout parameter to alter
+         * @param value new value of the layout parameter
+         */
+        public LayoutParamAction(int viewId, int property, int value) {
             this.viewId = viewId;
-            this.end = end;
+            this.property = property;
+            this.value = value;
         }
 
-        public ViewMarginEndAction(Parcel parcel) {
+        public LayoutParamAction(Parcel parcel) {
             viewId = parcel.readInt();
-            end = parcel.readInt();
+            property = parcel.readInt();
+            value = parcel.readInt();
         }
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(TAG);
             dest.writeInt(viewId);
-            dest.writeInt(end);
+            dest.writeInt(property);
+            dest.writeInt(value);
         }
 
         @Override
@@ -1849,17 +1863,31 @@
                 return;
             }
             ViewGroup.LayoutParams layoutParams = target.getLayoutParams();
-            if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
-                ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(end);
-                target.setLayoutParams(layoutParams);
+            if (layoutParams == null) {
+                return;
+            }
+            switch (property) {
+                case LAYOUT_MARGIN_END:
+                    if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
+                        ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(value);
+                        target.setLayoutParams(layoutParams);
+                    }
+                    break;
+                case LAYOUT_WIDTH:
+                    layoutParams.width = value;
+                    target.setLayoutParams(layoutParams);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown property " + property);
             }
         }
 
         public String getActionName() {
-            return "ViewMarginEndAction";
+            return "LayoutParamAction" + property + ".";
         }
 
-        int end;
+        int property;
+        int value;
 
         public final static int TAG = 19;
     }
@@ -2169,8 +2197,8 @@
                         case SetRemoteInputsAction.TAG:
                             mActions.add(new SetRemoteInputsAction(parcel));
                             break;
-                        case ViewMarginEndAction.TAG:
-                            mActions.add(new ViewMarginEndAction(parcel));
+                        case LayoutParamAction.TAG:
+                            mActions.add(new LayoutParamAction(parcel));
                             break;
                         default:
                             throw new ActionException("Tag " + tag + " not found");
@@ -2788,7 +2816,15 @@
      * @param endMargin the left padding in pixels
      */
     public void setViewLayoutMarginEnd(int viewId, int endMargin) {
-        addAction(new ViewMarginEndAction(viewId, endMargin));
+        addAction(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_MARGIN_END, endMargin));
+    }
+
+    /**
+     * Equivalent to setting {@link android.view.ViewGroup.LayoutParams#width}.
+     * @hide
+     */
+    public void setViewLayoutWidth(int viewId, int layoutWidth) {
+        mActions.add(new LayoutParamAction(viewId, LayoutParamAction.LAYOUT_WIDTH, layoutWidth));
     }
 
     /**
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 5953a98..8278c5a 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -18,11 +18,13 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 
 import android.Manifest;
+import android.appwidget.AppWidgetHostView;
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +36,9 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.MeasureSpec;
@@ -74,7 +79,7 @@
     private RemoteViewsAdapterServiceConnection mServiceConnection;
     private WeakReference<RemoteAdapterConnectionCallback> mCallback;
     private OnClickHandler mRemoteViewsOnClickHandler;
-    private FixedSizeRemoteViewsCache mCache;
+    private final FixedSizeRemoteViewsCache mCache;
     private int mVisibleWindowLowerBound;
     private int mVisibleWindowUpperBound;
 
@@ -92,13 +97,10 @@
 
     // We cache the FixedSizeRemoteViewsCaches across orientation. These are the related data
     // structures;
-    private static final HashMap<RemoteViewsCacheKey,
-            FixedSizeRemoteViewsCache> sCachedRemoteViewsCaches
-            = new HashMap<RemoteViewsCacheKey,
-                    FixedSizeRemoteViewsCache>();
+    private static final HashMap<RemoteViewsCacheKey, FixedSizeRemoteViewsCache>
+            sCachedRemoteViewsCaches = new HashMap<>();
     private static final HashMap<RemoteViewsCacheKey, Runnable>
-            sRemoteViewsCacheRemoveRunnables
-            = new HashMap<RemoteViewsCacheKey, Runnable>();
+            sRemoteViewsCacheRemoveRunnables = new HashMap<>();
 
     private static HandlerThread sCacheRemovalThread;
     private static Handler sCacheRemovalQueue;
@@ -286,9 +288,12 @@
      * A FrameLayout which contains a loading view, and manages the re/applying of RemoteViews when
      * they are loaded.
      */
-    private static class RemoteViewsFrameLayout extends FrameLayout {
-        public RemoteViewsFrameLayout(Context context) {
+    private static class RemoteViewsFrameLayout extends AppWidgetHostView {
+        private final FixedSizeRemoteViewsCache mCache;
+
+        public RemoteViewsFrameLayout(Context context, FixedSizeRemoteViewsCache cache) {
             super(context);
+            mCache = cache;
         }
 
         /**
@@ -297,13 +302,24 @@
          *             successfully.
          */
         public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler) {
-            try {
-                // Remove all the children of this layout first
-                removeAllViews();
-                addView(view.apply(getContext(), this, handler));
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to apply RemoteViews.");
-            }
+            setOnClickHandler(handler);
+            applyRemoteViews(view);
+        }
+
+        @Override
+        protected View getDefaultView() {
+            return mCache.getMetaData().createDefaultLoadingView(this);
+        }
+
+        @Override
+        protected Context getRemoteContext() {
+            return null;
+        }
+
+        @Override
+        protected View getErrorView() {
+            // Use the default loading view as the error view.
+            return getDefaultView();
         }
     }
 
@@ -312,29 +328,21 @@
      * adapter that have not yet had their RemoteViews loaded.
      */
     private class RemoteViewsFrameLayoutRefSet {
-        private HashMap<Integer, LinkedList<RemoteViewsFrameLayout>> mReferences;
-        private HashMap<RemoteViewsFrameLayout, LinkedList<RemoteViewsFrameLayout>>
-                mViewToLinkedList;
-
-        public RemoteViewsFrameLayoutRefSet() {
-            mReferences = new HashMap<Integer, LinkedList<RemoteViewsFrameLayout>>();
-            mViewToLinkedList =
-                    new HashMap<RemoteViewsFrameLayout, LinkedList<RemoteViewsFrameLayout>>();
-        }
+        private final SparseArray<LinkedList<RemoteViewsFrameLayout>> mReferences =
+                new SparseArray<>();
+        private final HashMap<RemoteViewsFrameLayout, LinkedList<RemoteViewsFrameLayout>>
+                mViewToLinkedList = new HashMap<>();
 
         /**
          * Adds a new reference to a RemoteViewsFrameLayout returned by the adapter.
          */
         public void add(int position, RemoteViewsFrameLayout layout) {
-            final Integer pos = position;
-            LinkedList<RemoteViewsFrameLayout> refs;
+            LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position);
 
             // Create the list if necessary
-            if (mReferences.containsKey(pos)) {
-                refs = mReferences.get(pos);
-            } else {
+            if (refs == null) {
                 refs = new LinkedList<RemoteViewsFrameLayout>();
-                mReferences.put(pos, refs);
+                mReferences.put(position, refs);
             }
             mViewToLinkedList.put(layout, refs);
 
@@ -349,10 +357,9 @@
         public void notifyOnRemoteViewsLoaded(int position, RemoteViews view) {
             if (view == null) return;
 
-            final Integer pos = position;
-            if (mReferences.containsKey(pos)) {
+            final LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(position);
+            if (refs != null) {
                 // Notify all the references for that position of the newly loaded RemoteViews
-                final LinkedList<RemoteViewsFrameLayout> refs = mReferences.get(pos);
                 for (final RemoteViewsFrameLayout ref : refs) {
                     ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler);
                     if (mViewToLinkedList.containsKey(ref)) {
@@ -361,7 +368,7 @@
                 }
                 refs.clear();
                 // Remove this set from the original mapping
-                mReferences.remove(pos);
+                mReferences.remove(position);
             }
         }
 
@@ -402,7 +409,7 @@
         int mFirstViewHeight;
 
         // A mapping from type id to a set of unique type ids
-        private final HashMap<Integer, Integer> mTypeIdIndexMap = new HashMap<Integer, Integer>();
+        private final SparseIntArray mTypeIdIndexMap = new SparseIntArray();
 
         public RemoteViewsMetaData() {
             reset();
@@ -438,82 +445,47 @@
         }
 
         public int getMappedViewType(int typeId) {
-            if (mTypeIdIndexMap.containsKey(typeId)) {
-                return mTypeIdIndexMap.get(typeId);
-            } else {
+            int mappedTypeId = mTypeIdIndexMap.get(typeId, -1);
+            if (mappedTypeId == -1) {
                 // We +1 because the loading view always has view type id of 0
-                int incrementalTypeId = mTypeIdIndexMap.size() + 1;
-                mTypeIdIndexMap.put(typeId, incrementalTypeId);
-                return incrementalTypeId;
+                mappedTypeId = mTypeIdIndexMap.size() + 1;
+                mTypeIdIndexMap.put(typeId, mappedTypeId);
             }
+            return mappedTypeId;
         }
 
         public boolean isViewTypeInRange(int typeId) {
             int mappedType = getMappedViewType(typeId);
-            if (mappedType >= viewTypeCount) {
-                return false;
-            } else {
-                return true;
-            }
+            return (mappedType < viewTypeCount);
         }
 
-        private RemoteViewsFrameLayout createLoadingView(int position, View convertView,
-                ViewGroup parent, Object lock, LayoutInflater layoutInflater, OnClickHandler
-                handler) {
-            // Create and return a new FrameLayout, and setup the references for this position
+        /**
+         * Creates a default loading view. Uses the size of the first row as a guide for the
+         * size of the loading view.
+         */
+        private synchronized View createDefaultLoadingView(ViewGroup parent) {
             final Context context = parent.getContext();
-            RemoteViewsFrameLayout layout = new RemoteViewsFrameLayout(context);
-
-            // Create a new loading view
-            synchronized (lock) {
-                boolean customLoadingViewAvailable = false;
-
-                if (mUserLoadingView != null) {
-                    // Try to inflate user-specified loading view
-                    try {
-                        View loadingView = mUserLoadingView.apply(parent.getContext(), parent,
-                                handler);
-                        loadingView.setTagInternal(com.android.internal.R.id.rowTypeId,
-                                new Integer(0));
-                        layout.addView(loadingView);
-                        customLoadingViewAvailable = true;
-                    } catch (Exception e) {
-                        Log.w(TAG, "Error inflating custom loading view, using default loading" +
-                                "view instead", e);
-                    }
+            if (mFirstViewHeight < 0) {
+                try {
+                    View firstView = mFirstView.apply(parent.getContext(), parent);
+                    firstView.measure(
+                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+                    mFirstViewHeight = firstView.getMeasuredHeight();
+                } catch (Exception e) {
+                    float density = context.getResources().getDisplayMetrics().density;
+                    mFirstViewHeight = Math.round(sDefaultLoadingViewHeight * density);
+                    Log.w(TAG, "Error inflating first RemoteViews" + e);
                 }
-                if (!customLoadingViewAvailable) {
-                    // A default loading view
-                    // Use the size of the first row as a guide for the size of the loading view
-                    if (mFirstViewHeight < 0) {
-                        try {
-                            View firstView = mFirstView.apply(parent.getContext(), parent, handler);
-                            firstView.measure(
-                                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
-                                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
-                            mFirstViewHeight = firstView.getMeasuredHeight();
-                            mFirstView = null;
-                        } catch (Exception e) {
-                            float density = context.getResources().getDisplayMetrics().density;
-                            mFirstViewHeight = (int)
-                                    Math.round(sDefaultLoadingViewHeight * density);
-                            mFirstView = null;
-                            Log.w(TAG, "Error inflating first RemoteViews" + e);
-                        }
-                    }
-
-                    // Compose the loading view text
-                    TextView loadingTextView = (TextView) layoutInflater.inflate(
-                            com.android.internal.R.layout.remote_views_adapter_default_loading_view,
-                            layout, false);
-                    loadingTextView.setHeight(mFirstViewHeight);
-                    loadingTextView.setTag(new Integer(0));
-
-                    layout.addView(loadingTextView);
-                }
+                mFirstView = null;
             }
 
-            return layout;
+            // Compose the loading view text
+            TextView loadingTextView = (TextView) LayoutInflater.from(context).inflate(
+                    com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+                    parent, false);
+            loadingTextView.setHeight(mFirstViewHeight);
+            return loadingTextView;
         }
     }
 
@@ -548,8 +520,8 @@
         // The meta data objects are made final so that they can be locked on independently
         // of the FixedSizeRemoteViewsCache. If we ever lock on both meta data objects, it is in
         // the order mTemporaryMetaData followed by mMetaData.
-        private final RemoteViewsMetaData mMetaData;
-        private final RemoteViewsMetaData mTemporaryMetaData;
+        private final RemoteViewsMetaData mMetaData = new RemoteViewsMetaData();
+        private final RemoteViewsMetaData mTemporaryMetaData = new RemoteViewsMetaData();
 
         // The cache/mapping of position to RemoteViewsMetaData.  This set is guaranteed to be
         // greater than or equal to the set of RemoteViews.
@@ -558,22 +530,20 @@
         // the heavy RemoteViews around.  The RemoteViews cache is trimmed to fixed constraints wrt.
         // memory and size, but this metadata cache will retain information until the data at the
         // position is guaranteed as not being necessary any more (usually on notifyDataSetChanged).
-        private HashMap<Integer, RemoteViewsIndexMetaData> mIndexMetaData;
+        private final SparseArray<RemoteViewsIndexMetaData> mIndexMetaData = new SparseArray<>();
 
         // The cache of actual RemoteViews, which may be pruned if the cache gets too large, or uses
         // too much memory.
-        private HashMap<Integer, RemoteViews> mIndexRemoteViews;
+        private final SparseArray<RemoteViews> mIndexRemoteViews = new SparseArray<>();
 
-        // The set of indices that have been explicitly requested by the collection view
-        private HashSet<Integer> mRequestedIndices;
+        // An array of indices to load, Indices which are explicitely requested are set to true,
+        // and those determined by the preloading algorithm to prefetch are set to false.
+        private final SparseBooleanArray mIndicesToLoad = new SparseBooleanArray();
 
         // We keep a reference of the last requested index to determine which item to prune the
         // farthest items from when we hit the memory limit
         private int mLastRequestedIndex;
 
-        // The set of indices to load, including those explicitly requested, as well as those
-        // determined by the preloading algorithm to be prefetched
-        private HashSet<Integer> mLoadIndices;
 
         // The lower and upper bounds of the preloaded range
         private int mPreloadLowerBound;
@@ -584,8 +554,8 @@
         // The maxCountSlack is used to determine if a new position in the cache to be loaded is
         // sufficiently ouside the old set, prompting a shifting of the "window" of items to be
         // preloaded.
-        private int mMaxCount;
-        private int mMaxCountSlack;
+        private final int mMaxCount;
+        private final int mMaxCountSlack;
         private static final float sMaxCountSlackPercent = 0.75f;
         private static final int sMaxMemoryLimitInBytes = 2 * 1024 * 1024;
 
@@ -594,17 +564,10 @@
             mMaxCountSlack = Math.round(sMaxCountSlackPercent * (mMaxCount / 2));
             mPreloadLowerBound = 0;
             mPreloadUpperBound = -1;
-            mMetaData = new RemoteViewsMetaData();
-            mTemporaryMetaData = new RemoteViewsMetaData();
-            mIndexMetaData = new HashMap<Integer, RemoteViewsIndexMetaData>();
-            mIndexRemoteViews = new HashMap<Integer, RemoteViews>();
-            mRequestedIndices = new HashSet<Integer>();
             mLastRequestedIndex = -1;
-            mLoadIndices = new HashSet<Integer>();
         }
 
-        public void insert(int position, RemoteViews v, long itemId,
-                ArrayList<Integer> visibleWindow) {
+        public void insert(int position, RemoteViews v, long itemId, int[] visibleWindow) {
             // Trim the cache if we go beyond the count
             if (mIndexRemoteViews.size() >= mMaxCount) {
                 mIndexRemoteViews.remove(getFarthestPositionFrom(position, visibleWindow));
@@ -630,8 +593,8 @@
             }
 
             // Update the metadata cache
-            if (mIndexMetaData.containsKey(position)) {
-                final RemoteViewsIndexMetaData metaData = mIndexMetaData.get(position);
+            final RemoteViewsIndexMetaData metaData = mIndexMetaData.get(position);
+            if (metaData != null) {
                 metaData.set(v, itemId);
             } else {
                 mIndexMetaData.put(position, new RemoteViewsIndexMetaData(v, itemId));
@@ -646,16 +609,10 @@
             return mTemporaryMetaData;
         }
         public RemoteViews getRemoteViewsAt(int position) {
-            if (mIndexRemoteViews.containsKey(position)) {
-                return mIndexRemoteViews.get(position);
-            }
-            return null;
+            return mIndexRemoteViews.get(position);
         }
         public RemoteViewsIndexMetaData getMetaDataAt(int position) {
-            if (mIndexMetaData.containsKey(position)) {
-                return mIndexMetaData.get(position);
-            }
-            return null;
+            return mIndexMetaData.get(position);
         }
 
         public void commitTemporaryMetaData() {
@@ -669,8 +626,8 @@
         private int getRemoteViewsBitmapMemoryUsage() {
             // Calculate the memory usage of all the RemoteViews bitmaps being cached
             int mem = 0;
-            for (Integer i : mIndexRemoteViews.keySet()) {
-                final RemoteViews v = mIndexRemoteViews.get(i);
+            for (int i = mIndexRemoteViews.size() - 1; i >= 0; i--) {
+                final RemoteViews v = mIndexRemoteViews.valueAt(i);
                 if (v != null) {
                     mem += v.estimateMemoryUsage();
                 }
@@ -678,24 +635,25 @@
             return mem;
         }
 
-        private int getFarthestPositionFrom(int pos, ArrayList<Integer> visibleWindow) {
+        private int getFarthestPositionFrom(int pos, int[] visibleWindow) {
             // Find the index farthest away and remove that
             int maxDist = 0;
             int maxDistIndex = -1;
             int maxDistNotVisible = 0;
             int maxDistIndexNotVisible = -1;
-            for (int i : mIndexRemoteViews.keySet()) {
-                int dist = Math.abs(i-pos);
-                if (dist > maxDistNotVisible && !visibleWindow.contains(i)) {
+            for (int i = mIndexRemoteViews.size() - 1; i >= 0; i--) {
+                int index = mIndexRemoteViews.keyAt(i);
+                int dist = Math.abs(index-pos);
+                if (dist > maxDistNotVisible && Arrays.binarySearch(visibleWindow, index) < 0) {
                     // maxDistNotVisible/maxDistIndexNotVisible will store the index of the
                     // farthest non-visible position
-                    maxDistIndexNotVisible = i;
+                    maxDistIndexNotVisible = index;
                     maxDistNotVisible = dist;
                 }
                 if (dist >= maxDist) {
                     // maxDist/maxDistIndex will store the index of the farthest position
                     // regardless of whether it is visible or not
-                    maxDistIndex = i;
+                    maxDistIndex = index;
                     maxDist = dist;
                 }
             }
@@ -707,9 +665,8 @@
 
         public void queueRequestedPositionToLoad(int position) {
             mLastRequestedIndex = position;
-            synchronized (mLoadIndices) {
-                mRequestedIndices.add(position);
-                mLoadIndices.add(position);
+            synchronized (mIndicesToLoad) {
+                mIndicesToLoad.put(position, true);
             }
         }
         public boolean queuePositionsToBePreloadedFromRequestedPosition(int position) {
@@ -725,11 +682,13 @@
             synchronized (mMetaData) {
                 count = mMetaData.count;
             }
-            synchronized (mLoadIndices) {
-                mLoadIndices.clear();
-
-                // Add all the requested indices
-                mLoadIndices.addAll(mRequestedIndices);
+            synchronized (mIndicesToLoad) {
+                // Remove all indices which have not been previously requested.
+                for (int i = mIndicesToLoad.size() - 1; i >= 0; i--) {
+                    if (!mIndicesToLoad.valueAt(i)) {
+                        mIndicesToLoad.removeAt(i);
+                    }
+                }
 
                 // Add all the preload indices
                 int halfMaxCount = mMaxCount / 2;
@@ -738,43 +697,40 @@
                 int effectiveLowerBound = Math.max(0, mPreloadLowerBound);
                 int effectiveUpperBound = Math.min(mPreloadUpperBound, count - 1);
                 for (int i = effectiveLowerBound; i <= effectiveUpperBound; ++i) {
-                    mLoadIndices.add(i);
+                    if (mIndexRemoteViews.indexOfKey(i) < 0 && !mIndicesToLoad.get(i)) {
+                        // If the index has not been requested, and has not been loaded.
+                        mIndicesToLoad.put(i, false);
+                    }
                 }
-
-                // But remove all the indices that have already been loaded and are cached
-                mLoadIndices.removeAll(mIndexRemoteViews.keySet());
             }
             return true;
         }
-        /** Returns the next index to load, and whether that index was directly requested or not */
-        public int[] getNextIndexToLoad() {
+        /** Returns the next index to load */
+        public int getNextIndexToLoad() {
             // We try and prioritize items that have been requested directly, instead
             // of items that are loaded as a result of the caching mechanism
-            synchronized (mLoadIndices) {
+            synchronized (mIndicesToLoad) {
                 // Prioritize requested indices to be loaded first
-                if (!mRequestedIndices.isEmpty()) {
-                    Integer i = mRequestedIndices.iterator().next();
-                    mRequestedIndices.remove(i);
-                    mLoadIndices.remove(i);
-                    return new int[]{i.intValue(), 1};
+                int index = mIndicesToLoad.indexOfValue(true);
+                if (index < 0) {
+                    // Otherwise, preload other indices as necessary
+                    index = mIndicesToLoad.indexOfValue(false);
                 }
-
-                // Otherwise, preload other indices as necessary
-                if (!mLoadIndices.isEmpty()) {
-                    Integer i = mLoadIndices.iterator().next();
-                    mLoadIndices.remove(i);
-                    return new int[]{i.intValue(), 0};
+                if (index < 0) {
+                    return -1;
+                } else {
+                    int key = mIndicesToLoad.keyAt(index);
+                    mIndicesToLoad.removeAt(index);
+                    return key;
                 }
-
-                return new int[]{-1, 0};
             }
         }
 
         public boolean containsRemoteViewAt(int position) {
-            return mIndexRemoteViews.containsKey(position);
+            return mIndexRemoteViews.indexOfKey(position) >= 0;
         }
         public boolean containsMetaDataAt(int position) {
-            return mIndexMetaData.containsKey(position);
+            return mIndexMetaData.indexOfKey(position) >= 0;
         }
 
         public void reset() {
@@ -787,9 +743,8 @@
             mLastRequestedIndex = -1;
             mIndexRemoteViews.clear();
             mIndexMetaData.clear();
-            synchronized (mLoadIndices) {
-                mRequestedIndices.clear();
-                mLoadIndices.clear();
+            synchronized (mIndicesToLoad) {
+                mIndicesToLoad.clear();
             }
         }
     }
@@ -942,8 +897,7 @@
                     // Get the next index to load
                     int position = -1;
                     synchronized (mCache) {
-                        int[] res = mCache.getNextIndexToLoad();
-                        position = res[0];
+                        position = mCache.getNextIndexToLoad();
                     }
                     if (position > -1) {
                         // Load the item, and notify any existing RemoteViewsFrameLayouts
@@ -1048,7 +1002,7 @@
         }
         synchronized (mCache) {
             if (viewTypeInRange) {
-                ArrayList<Integer> visibleWindow = getVisibleWindow(mVisibleWindowLowerBound,
+                int[] visibleWindow = getVisibleWindow(mVisibleWindowLowerBound,
                         mVisibleWindowUpperBound, cacheCount);
                 // Cache the RemoteViews we loaded
                 mCache.insert(position, remoteViews, itemId, visibleWindow);
@@ -1117,21 +1071,6 @@
     }
 
     /**
-     * Returns the item type id for the specified convert view.  Returns -1 if the convert view
-     * is invalid.
-     */
-    private int getConvertViewTypeId(View convertView) {
-        int typeId = -1;
-        if (convertView != null) {
-            Object tag = convertView.getTag(com.android.internal.R.id.rowTypeId);
-            if (tag != null) {
-                typeId = (Integer) tag;
-            }
-        }
-        return typeId;
-    }
-
-    /**
      * This method allows an AdapterView using this Adapter to provide information about which
      * views are currently being displayed. This allows for certain optimizations and preloading
      * which  wouldn't otherwise be possible.
@@ -1145,7 +1084,8 @@
         // "Request" an index so that we can queue it for loading, initiate subsequent
         // preloading, etc.
         synchronized (mCache) {
-            boolean isInCache = mCache.containsRemoteViewAt(position);
+            RemoteViews rv = mCache.getRemoteViewsAt(position);
+            boolean isInCache = (rv != null);
             boolean isConnected = mServiceConnection.isConnected();
             boolean hasNewItems = false;
 
@@ -1162,75 +1102,23 @@
                 hasNewItems = mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
             }
 
+            final RemoteViewsFrameLayout layout =
+                    (convertView instanceof RemoteViewsFrameLayout)
+                            ? (RemoteViewsFrameLayout) convertView
+                            : new RemoteViewsFrameLayout(parent.getContext(), mCache);
             if (isInCache) {
-                View convertViewChild = null;
-                int convertViewTypeId = 0;
-                RemoteViewsFrameLayout layout = null;
-
-                if (convertView instanceof RemoteViewsFrameLayout) {
-                    layout = (RemoteViewsFrameLayout) convertView;
-                    convertViewChild = layout.getChildAt(0);
-                    convertViewTypeId = getConvertViewTypeId(convertViewChild);
-                }
-
-                // Second, we try and retrieve the RemoteViews from the cache, returning a loading
-                // view and queueing it to be loaded if it has not already been loaded.
-                Context context = parent.getContext();
-                RemoteViews rv = mCache.getRemoteViewsAt(position);
-                RemoteViewsIndexMetaData indexMetaData = mCache.getMetaDataAt(position);
-                int typeId = indexMetaData.typeId;
-
-                try {
-                    // Reuse the convert view where possible
-                    if (layout != null) {
-                        if (convertViewTypeId == typeId) {
-                            rv.reapply(context, convertViewChild, mRemoteViewsOnClickHandler);
-                            return layout;
-                        }
-                        layout.removeAllViews();
-                    } else {
-                        layout = new RemoteViewsFrameLayout(context);
-                    }
-
-                    // Otherwise, create a new view to be returned
-                    View newView = rv.apply(context, parent, mRemoteViewsOnClickHandler);
-                    newView.setTagInternal(com.android.internal.R.id.rowTypeId,
-                            new Integer(typeId));
-                    layout.addView(newView);
-                    return layout;
-
-                } catch (Exception e){
-                    // We have to make sure that we successfully inflated the RemoteViews, if not
-                    // we return the loading view instead.
-                    Log.w(TAG, "Error inflating RemoteViews at position: " + position + ", using" +
-                            "loading view instead" + e);
-
-                    RemoteViewsFrameLayout loadingView = null;
-                    final RemoteViewsMetaData metaData = mCache.getMetaData();
-                    synchronized (metaData) {
-                        loadingView = metaData.createLoadingView(position, convertView, parent,
-                                mCache, mLayoutInflater, mRemoteViewsOnClickHandler);
-                    }
-                    return loadingView;
-                } finally {
-                    if (hasNewItems) loadNextIndexInBackground();
-                }
+                layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler);
+                if (hasNewItems) loadNextIndexInBackground();
             } else {
-                // If the cache does not have the RemoteViews at this position, then create a
-                // loading view and queue the actual position to be loaded in the background
-                RemoteViewsFrameLayout loadingView = null;
-                final RemoteViewsMetaData metaData = mCache.getMetaData();
-                synchronized (metaData) {
-                    loadingView = metaData.createLoadingView(position, convertView, parent,
-                            mCache, mLayoutInflater, mRemoteViewsOnClickHandler);
-                }
-
-                mRequestedViews.add(position, loadingView);
+                // If the views is not loaded, apply the loading view. If the loading view doesn't
+                // exist, the layout will create a default view based on the firstView height.
+                layout.onRemoteViewsLoaded(mCache.getMetaData().mUserLoadingView,
+                        mRemoteViewsOnClickHandler);
+                mRequestedViews.add(position, layout);
                 mCache.queueRequestedPositionToLoad(position);
                 loadNextIndexInBackground();
-
-                return loadingView;
             }
+            return layout;
         }
     }
 
@@ -1276,7 +1164,7 @@
         // Re-request the new metadata (only after the notification to the factory)
         updateTemporaryMetaData();
         int newCount;
-        ArrayList<Integer> visibleWindow;
+        int[] visibleWindow;
         synchronized(mCache.getTemporaryMetaData()) {
             newCount = mCache.getTemporaryMetaData().count;
             visibleWindow = getVisibleWindow(mVisibleWindowLowerBound,
@@ -1311,26 +1199,33 @@
         mNotifyDataSetChangedAfterOnServiceConnected = false;
     }
 
-    private ArrayList<Integer> getVisibleWindow(int lower, int upper, int count) {
-        ArrayList<Integer> window = new ArrayList<Integer>();
-
+    /**
+     * Returns a sorted array of all integers between lower and upper.
+     */
+    private int[] getVisibleWindow(int lower, int upper, int count) {
         // In the case that the window is invalid or uninitialized, return an empty window.
         if ((lower == 0 && upper == 0) || lower < 0 || upper < 0) {
-            return window;
+            return new int[0];
         }
 
+        int[] window;
         if (lower <= upper) {
-            for (int i = lower;  i <= upper; i++){
-                window.add(i);
+            window = new int[upper + 1 - lower];
+            for (int i = lower, j = 0;  i <= upper; i++, j++){
+                window[j] = i;
             }
         } else {
             // If the upper bound is less than the lower bound it means that the visible window
             // wraps around.
-            for (int i = lower; i < count; i++) {
-                window.add(i);
+            count = Math.max(count, lower);
+            window = new int[count - lower + upper + 1];
+            int j = 0;
+            // Add the entries in sorted order
+            for (int i = 0; i <= upper; i++, j++) {
+                window[j] = i;
             }
-            for (int i = 0; i <= upper; i++) {
-                window.add(i);
+            for (int i = lower; i < count; i++, j++) {
+                window[j] = i;
             }
         }
         return window;
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 45fc6c3..3796df7 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -36,6 +36,8 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.speech.RecognizerIntent;
 import android.text.Editable;
 import android.text.InputType;
@@ -1332,6 +1334,48 @@
         setIconified(false);
     }
 
+    static class SavedState extends BaseSavedState {
+        boolean isIconified;
+
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public SavedState(Parcel source) {
+            super(source);
+            isIconified = (Boolean) source.readValue(null);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeValue(isIconified);
+        }
+
+        @Override
+        public String toString() {
+            return "SearchView.SavedState{"
+                    + Integer.toHexString(System.identityHashCode(this))
+                    + " isIconified=" + isIconified + "}";
+        }
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        SavedState ss = new SavedState(superState);
+        ss.isIconified = isIconified();
+        return ss;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        updateViewsVisibility(ss.isIconified);
+        requestLayout();
+    }
+
     @Override
     public CharSequence getAccessibilityClassName() {
         return SearchView.class.getName();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 712a04b..95fcdc1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4101,36 +4101,42 @@
         Parcelable superState = super.onSaveInstanceState();
 
         // Save state if we are forced to
-        boolean save = mFreezesText;
-        int start = 0;
-        int end = 0;
+        final boolean freezesText = getFreezesText();
+        boolean hasSelection = false;
+        int start = -1;
+        int end = -1;
 
         if (mText != null) {
             start = getSelectionStart();
             end = getSelectionEnd();
             if (start >= 0 || end >= 0) {
                 // Or save state if there is a selection
-                save = true;
+                hasSelection = true;
             }
         }
 
-        if (save) {
+        if (freezesText || hasSelection) {
             SavedState ss = new SavedState(superState);
-            // XXX Should also save the current scroll position!
-            ss.selStart = start;
-            ss.selEnd = end;
 
-            if (mText instanceof Spanned) {
-                Spannable sp = new SpannableStringBuilder(mText);
+            if (freezesText) {
+                if (mText instanceof Spanned) {
+                    final Spannable sp = new SpannableStringBuilder(mText);
 
-                if (mEditor != null) {
-                    removeMisspelledSpans(sp);
-                    sp.removeSpan(mEditor.mSuggestionRangeSpan);
+                    if (mEditor != null) {
+                        removeMisspelledSpans(sp);
+                        sp.removeSpan(mEditor.mSuggestionRangeSpan);
+                    }
+
+                    ss.text = sp;
+                } else {
+                    ss.text = mText.toString();
                 }
+            }
 
-                ss.text = sp;
-            } else {
-                ss.text = mText.toString();
+            if (hasSelection) {
+                // XXX Should also save the current scroll position!
+                ss.selStart = start;
+                ss.selEnd = end;
             }
 
             if (isFocused() && start >= 0 && end >= 0) {
@@ -4224,7 +4230,9 @@
      * position.  By default this is false, not saving the text.  Set to true
      * if the text in the text view is not being saved somewhere else in
      * persistent storage (such as in a content provider) so that if the
-     * view is later thawed the user will not lose their data.
+     * view is later thawed the user will not lose their data. For
+     * {@link android.widget.EditText} it is always enabled, regardless of
+     * the value of the attribute.
      *
      * @param freezesText Controls whether a frozen icicle should include the
      * entire text data: true to include it, false to not.
@@ -4238,7 +4246,7 @@
 
     /**
      * Return whether this text view is including its entire text contents
-     * in frozen icicles.
+     * in frozen icicles. For {@link android.widget.EditText} it always returns true.
      *
      * @return Returns true if text is included, false if it isn't.
      *
@@ -5452,15 +5460,9 @@
         return (int) Math.max(0, mShadowDy + mShadowRadius);
     }
 
-    private int getFudgedPaddingRight() {
-        // Add sufficient space for cursor and tone marks
-        int cursorWidth = 2 + (int)mTextPaint.density; // adequate for Material cursors
-        return Math.max(0, getCompoundPaddingRight() - (cursorWidth - 1));
-    }
-
     @Override
     protected int getRightPaddingOffset() {
-        return -(getFudgedPaddingRight() - mPaddingRight) +
+        return -(getCompoundPaddingRight() - mPaddingRight) +
                 (int) Math.max(0, mShadowDx + mShadowRadius);
     }
 
@@ -5805,7 +5807,7 @@
 
         float clipLeft = compoundPaddingLeft + scrollX;
         float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY;
-        float clipRight = right - left - getFudgedPaddingRight() + scrollX;
+        float clipRight = right - left - getCompoundPaddingRight() + scrollX;
         float clipBottom = bottom - top + scrollY -
                 ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom);
 
@@ -6851,11 +6853,11 @@
                         .setLineSpacing(mSpacingAdd, mSpacingMult)
                         .setIncludePad(mIncludePad)
                         .setBreakStrategy(mBreakStrategy)
-                        .setHyphenationFrequency(mHyphenationFrequency);
+                        .setHyphenationFrequency(mHyphenationFrequency)
+                        .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
                 if (shouldEllipsize) {
                     builder.setEllipsize(mEllipsize)
-                            .setEllipsizedWidth(ellipsisWidth)
-                            .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
+                            .setEllipsizedWidth(ellipsisWidth);
                 }
                 mHintLayout = builder.build();
             }
@@ -6942,11 +6944,12 @@
                     .setLineSpacing(mSpacingAdd, mSpacingMult)
                     .setIncludePad(mIncludePad)
                     .setBreakStrategy(mBreakStrategy)
-                    .setHyphenationFrequency(mHyphenationFrequency);
+                    .setHyphenationFrequency(mHyphenationFrequency)
+                    .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
             if (shouldEllipsize) {
                 builder.setEllipsize(effectiveEllipsize)
-                        .setEllipsizedWidth(ellipsisWidth)
-                        .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
+                        .setEllipsizedWidth(ellipsisWidth);
+
             }
             // TODO: explore always setting maxLines
             result = builder.build();
@@ -10111,8 +10114,8 @@
      * {@link View#onSaveInstanceState}.
      */
     public static class SavedState extends BaseSavedState {
-        int selStart;
-        int selEnd;
+        int selStart = -1;
+        int selEnd = -1;
         CharSequence text;
         boolean frozenWithFocus;
         CharSequence error;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index b0fb93b..8c3c2b5 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -45,6 +45,7 @@
 import android.os.ResultReceiver;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.provider.DocumentsContract;
 import android.service.chooser.ChooserTarget;
 import android.service.chooser.ChooserTargetService;
@@ -128,6 +129,7 @@
                     if (mServiceConnections.isEmpty()) {
                         mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
                         sendVoiceChoicesIfNeeded();
+                        mChooserListAdapter.setShowServiceTargets(true);
                     }
                     break;
 
@@ -137,6 +139,7 @@
                     }
                     unbindRemainingServices();
                     sendVoiceChoicesIfNeeded();
+                    mChooserListAdapter.setShowServiceTargets(true);
                     break;
 
                 default:
@@ -232,7 +235,7 @@
         // the case where we don't have access to credential encrypted storage we just won't
         // have our pinned target info.
         final File prefsFile = new File(new File(
-                Environment.getDataUserCredentialEncryptedPackageDirectory(null,
+                Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL,
                         context.getUserId(), context.getPackageName()),
                 "shared_prefs"),
                 PINNED_SHARED_PREFS_NAME + ".xml");
@@ -765,6 +768,7 @@
 
         private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
         private final List<TargetInfo> mCallerTargets = new ArrayList<>();
+        private boolean mShowServiceTargets;
 
         private float mLateFee = 1.f;
 
@@ -865,6 +869,9 @@
         }
 
         public int getServiceTargetCount() {
+            if (!mShowServiceTargets) {
+                return 0;
+            }
             return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
         }
 
@@ -954,6 +961,14 @@
             notifyDataSetChanged();
         }
 
+        /**
+         * Set to true to reveal all service targets at once.
+         */
+        public void setShowServiceTargets(boolean show) {
+            mShowServiceTargets = show;
+            notifyDataSetChanged();
+        }
+
         private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) {
             final float newScore = chooserTargetInfo.getModifiedScore();
             for (int i = 0, N = mServiceTargets.size(); i < N; i++) {
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index 9de4a6c..f4c18c3 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -33,10 +33,11 @@
 
     void deleteSoundModel(in ParcelUuid soundModelId);
 
-    void startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+    int startRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback,
+         in SoundTrigger.RecognitionConfig config);
 
     /**
      * Stops recognition.
      */
-    void stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
+    int stopRecognition(in ParcelUuid soundModelId, in IRecognitionStatusCallback callback);
 }
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 210adce..465c4d8 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -104,6 +104,9 @@
         }
 
         private boolean isSuggestionOfType(int suggestionMask) {
+            if (!mIsTranslated) { // Never suggest an untranslated locale
+                return false;
+            }
             return (mSuggestionFlags & suggestionMask) == suggestionMask;
         }
 
@@ -207,6 +210,27 @@
         }
     }
 
+    /*
+     * Show all the languages supported for a country in the suggested list.
+     * This is also handy for devices without SIM (tablets).
+     */
+    private static void addSuggestedLocalesForRegion(Locale locale) {
+        if (locale == null) {
+            return;
+        }
+        final String country = locale.getCountry();
+        if (country.isEmpty()) {
+            return;
+        }
+
+        for (LocaleInfo li : sLocaleCache.values()) {
+            if (country.equals(li.getLocale().getCountry())) {
+                // We don't need to differentiate between manual and SIM suggestions
+                li.mSuggestionFlags |= LocaleInfo.SUGGESTION_TYPE_SIM;
+            }
+        }
+    }
+
     public static void fillCache(Context context) {
         if (sFullyInitialized) {
             return;
@@ -256,6 +280,8 @@
             li.setTranslated(localizedLocales.contains(li.getLangScriptKey()));
         }
 
+        addSuggestedLocalesForRegion(Locale.getDefault());
+
         sFullyInitialized = true;
     }
 
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3fb768f..9897b12 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -174,10 +174,6 @@
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        // We're dispatching intents that might be coming from legacy apps, so
-        // don't kill ourselves.
-        StrictMode.disableDeathOnFileUriExposure();
-
         // Use a specialized prompt when we're handling the 'Home' app startActivity()
         final Intent intent = makeMyIntent();
         final Set<String> categories = intent.getCategories();
@@ -768,6 +764,17 @@
     }
 
     public void safelyStartActivity(TargetInfo cti) {
+        // We're dispatching intents that might be coming from legacy apps, so
+        // don't kill ourselves.
+        StrictMode.disableDeathOnFileUriExposure();
+        try {
+            safelyStartActivityInternal(cti);
+        } finally {
+            StrictMode.enableDeathOnFileUriExposure();
+        }
+    }
+
+    private void safelyStartActivityInternal(TargetInfo cti) {
         // If needed, show that intent is forwarded
         // from managed profile to owner or other way around.
         if (mProfileSwitchMessageId != -1) {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index f0c1094..4c63941 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -27,12 +28,12 @@
 import android.content.res.Resources;
 import android.os.RemoteException;
 import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Pair;
+import android.util.Printer;
 import android.util.Slog;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
@@ -769,7 +770,7 @@
     public static ArrayMap<String, ArraySet<String>> parseInputMethodsAndSubtypesString(
             @Nullable final String inputMethodsAndSubtypesString) {
 
-        final ArrayMap<String, ArraySet<String>> imeMap = new ArrayMap<String, ArraySet<String>>();
+        final ArrayMap<String, ArraySet<String>> imeMap = new ArrayMap<>();
         if (TextUtils.isEmpty(inputMethodsAndSubtypesString)) {
             return imeMap;
         }
@@ -784,7 +785,7 @@
                         typeSplitter,
                         subtypeSplitter);
         for (Pair<String, ArrayList<String>> ime : allImeSettings) {
-            ArraySet<String> subtypes = new ArraySet<String>();
+            ArraySet<String> subtypes = new ArraySet<>();
             if (ime.second != null) {
                 subtypes.addAll(ime.second);
             }
@@ -827,7 +828,14 @@
         private final HashMap<String, InputMethodInfo> mMethodMap;
         private final ArrayList<InputMethodInfo> mMethodList;
 
+        /**
+         * On-memory data store to emulate when {@link #mCopyOnWrite} is {@code true}.
+         */
+        private final HashMap<String, String> mCopyOnWriteDataStore = new HashMap<>();
+
+        private boolean mCopyOnWrite = false;
         private String mEnabledInputMethodsStrCache;
+        @UserIdInt
         private int mCurrentUserId;
         private int[] mCurrentProfileIds = new int[0];
 
@@ -880,23 +888,85 @@
             return imsList;
         }
 
+        @Deprecated
         public InputMethodSettings(
                 Resources res, ContentResolver resolver,
                 HashMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
-                int userId) {
-            setCurrentUserId(userId);
+                @UserIdInt int userId) {
+            this(res, resolver, methodMap, methodList, userId, false /* copyOnWrite */);
+        }
+
+        public InputMethodSettings(
+                Resources res, ContentResolver resolver,
+                HashMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList,
+                @UserIdInt int userId, boolean copyOnWrite) {
             mRes = res;
             mResolver = resolver;
             mMethodMap = methodMap;
             mMethodList = methodList;
+            switchCurrentUser(userId, copyOnWrite);
         }
 
-        public void setCurrentUserId(int userId) {
+        /**
+         * Must be called when the current user is changed.
+         *
+         * @param userId The user ID.
+         * @param copyOnWrite If {@code true}, for each settings key
+         * (e.g. {@link Settings.Secure#ACTION_INPUT_METHOD_SUBTYPE_SETTINGS}) we use the actual
+         * settings on the {@link Settings.Secure} until we do the first write operation.
+         */
+        public void switchCurrentUser(@UserIdInt int userId, boolean copyOnWrite) {
             if (DEBUG) {
-                Slog.d(TAG, "--- Swtich the current user from " + mCurrentUserId + " to " + userId);
+                Slog.d(TAG, "--- Switch the current user from " + mCurrentUserId + " to " + userId);
             }
-            // IMMS settings are kept per user, so keep track of current user
+            if (mCurrentUserId != userId || mCopyOnWrite != copyOnWrite) {
+                mCopyOnWriteDataStore.clear();
+                mEnabledInputMethodsStrCache = "";
+                // TODO: mCurrentProfileIds should be cleared here.
+            }
             mCurrentUserId = userId;
+            mCopyOnWrite = copyOnWrite;
+            // TODO: mCurrentProfileIds should be updated here.
+        }
+
+        private void putString(final String key, final String str) {
+            if (mCopyOnWrite) {
+                mCopyOnWriteDataStore.put(key, str);
+            } else {
+                Settings.Secure.putStringForUser(mResolver, key, str, mCurrentUserId);
+            }
+        }
+
+        private String getString(final String key) {
+            if (mCopyOnWrite && mCopyOnWriteDataStore.containsKey(key)) {
+                final String result = mCopyOnWriteDataStore.get(key);
+                return result != null ? result : "";
+            }
+            return Settings.Secure.getStringForUser(mResolver, key, mCurrentUserId);
+        }
+
+        private void putInt(final String key, final int value) {
+            if (mCopyOnWrite) {
+                mCopyOnWriteDataStore.put(key, String.valueOf(value));
+            } else {
+                Settings.Secure.putIntForUser(mResolver, key, value, mCurrentUserId);
+            }
+        }
+
+        private int getInt(final String key, final int defaultValue) {
+            if (mCopyOnWrite && mCopyOnWriteDataStore.containsKey(key)) {
+                final String result = mCopyOnWriteDataStore.get(key);
+                return result != null ? Integer.valueOf(result) : 0;
+            }
+            return Settings.Secure.getIntForUser(mResolver, key, defaultValue, mCurrentUserId);
+        }
+
+        private void putBoolean(final String key, final boolean value) {
+            putInt(key, value ? 1 : 0);
+        }
+
+        private boolean getBoolean(final String key, final boolean defaultValue) {
+            return getInt(key, defaultValue ? 1 : 0) == 1;
         }
 
         public void setCurrentProfileIds(int[] currentProfileIds) {
@@ -1035,17 +1105,15 @@
         }
 
         private void putEnabledInputMethodsStr(String str) {
-            Settings.Secure.putStringForUser(
-                    mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str, mCurrentUserId);
-            mEnabledInputMethodsStrCache = str;
             if (DEBUG) {
                 Slog.d(TAG, "putEnabledInputMethodStr: " + str);
             }
+            putString(Settings.Secure.ENABLED_INPUT_METHODS, str);
+            mEnabledInputMethodsStrCache = str;
         }
 
         public String getEnabledInputMethodsStr() {
-            mEnabledInputMethodsStrCache = Settings.Secure.getStringForUser(
-                    mResolver, Settings.Secure.ENABLED_INPUT_METHODS, mCurrentUserId);
+            mEnabledInputMethodsStrCache = getString(Settings.Secure.ENABLED_INPUT_METHODS);
             if (DEBUG) {
                 Slog.d(TAG, "getEnabledInputMethodsStr: " + mEnabledInputMethodsStrCache
                         + ", " + mCurrentUserId);
@@ -1103,8 +1171,7 @@
             if (DEBUG) {
                 Slog.d(TAG, "putSubtypeHistoryStr: " + str);
             }
-            Settings.Secure.putStringForUser(
-                    mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, str, mCurrentUserId);
+            putString(Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, str);
         }
 
         public Pair<String, String> getLastInputMethodAndSubtypeLocked() {
@@ -1222,12 +1289,11 @@
         }
 
         private String getSubtypeHistoryStr() {
+            final String history = getString(Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY);
             if (DEBUG) {
-                Slog.d(TAG, "getSubtypeHistoryStr: " + Settings.Secure.getStringForUser(
-                        mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, mCurrentUserId));
+                Slog.d(TAG, "getSubtypeHistoryStr: " + history);
             }
-            return Settings.Secure.getStringForUser(
-                    mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, mCurrentUserId);
+            return history;
         }
 
         public void putSelectedInputMethod(String imeId) {
@@ -1235,8 +1301,7 @@
                 Slog.d(TAG, "putSelectedInputMethodStr: " + imeId + ", "
                         + mCurrentUserId);
             }
-            Settings.Secure.putStringForUser(
-                    mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, imeId, mCurrentUserId);
+            putString(Settings.Secure.DEFAULT_INPUT_METHOD, imeId);
         }
 
         public void putSelectedSubtype(int subtypeId) {
@@ -1244,18 +1309,15 @@
                 Slog.d(TAG, "putSelectedInputMethodSubtypeStr: " + subtypeId + ", "
                         + mCurrentUserId);
             }
-            Settings.Secure.putIntForUser(mResolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
-                    subtypeId, mCurrentUserId);
+            putInt(Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtypeId);
         }
 
         public String getSelectedInputMethod() {
+            final String imi = getString(Settings.Secure.DEFAULT_INPUT_METHOD);
             if (DEBUG) {
-                Slog.d(TAG, "getSelectedInputMethodStr: " + Settings.Secure.getStringForUser(
-                        mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, mCurrentUserId)
-                        + ", " + mCurrentUserId);
+                Slog.d(TAG, "getSelectedInputMethodStr: " + imi);
             }
-            return Settings.Secure.getStringForUser(
-                    mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, mCurrentUserId);
+            return imi;
         }
 
         public boolean isSubtypeSelected() {
@@ -1263,24 +1325,18 @@
         }
 
         private int getSelectedInputMethodSubtypeHashCode() {
-            try {
-                return Settings.Secure.getIntForUser(
-                        mResolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, mCurrentUserId);
-            } catch (SettingNotFoundException e) {
-                return NOT_A_SUBTYPE_ID;
-            }
+            return getInt(Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, NOT_A_SUBTYPE_ID);
         }
 
         public boolean isShowImeWithHardKeyboardEnabled() {
-                return Settings.Secure.getIntForUser(mResolver,
-                        Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0, mCurrentUserId) == 1;
+            return getBoolean(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, false);
         }
 
         public void setShowImeWithHardKeyboard(boolean show) {
-            Settings.Secure.putIntForUser(mResolver, Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
-                    show ? 1 : 0, mCurrentUserId);
+            putBoolean(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, show);
         }
 
+        @UserIdInt
         public int getCurrentUserId() {
             return mCurrentUserId;
         }
@@ -1315,6 +1371,13 @@
             }
             return enabledInputMethodAndSubtypes;
         }
+
+        public void dumpLocked(final Printer pw, final String prefix) {
+            pw.println(prefix + "mCurrentUserId=" + mCurrentUserId);
+            pw.println(prefix + "mCurrentProfileIds=" + Arrays.toString(mCurrentProfileIds));
+            pw.println(prefix + "mCopyOnWrite=" + mCopyOnWrite);
+            pw.println(prefix + "mEnabledInputMethodsStrCache=" + mEnabledInputMethodsStrCache);
+        }
     }
 
     // For spell checker service manager.
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index d4ada95..af3f7ec 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -86,6 +86,8 @@
 import static android.view.Window.DECOR_CAPTION_SHADE_LIGHT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
 import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -615,7 +617,7 @@
                 if (h > 0) {
                     heightMeasureSpec = MeasureSpec.makeMeasureSpec(
                             Math.min(h, heightSize), EXACTLY);
-                } else if ((mWindow.getAttributes().flags & FLAG_FULLSCREEN) == 0) {
+                } else if ((mWindow.getAttributes().flags & FLAG_LAYOUT_IN_SCREEN) == 0) {
                     heightMeasureSpec = MeasureSpec.makeMeasureSpec(
                             heightSize - mFloatingInsets.top - mFloatingInsets.bottom, AT_MOST);
                     mApplyFloatingVerticalInsets = true;
@@ -890,10 +892,11 @@
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         final WindowManager.LayoutParams attrs = mWindow.getAttributes();
         mFloatingInsets.setEmpty();
-        if ((attrs.flags & FLAG_FULLSCREEN) == 0) {
+        if ((attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0) {
             // For dialog windows we want to make sure they don't go over the status bar or nav bar.
             // We consume the system insets and we will reuse them later during the measure phase.
-            // We allow the app to ignore this and handle insets itself by using FLAG_FULLSCREEN.
+            // We allow the app to ignore this and handle insets itself by using
+            // FLAG_LAYOUT_IN_SCREEN.
             if (attrs.height == WindowManager.LayoutParams.WRAP_CONTENT) {
                 mFloatingInsets.top = insets.getSystemWindowInsetTop();
                 mFloatingInsets.bottom = insets.getSystemWindowInsetBottom();
@@ -1000,13 +1003,25 @@
                         && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
                         && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
 
+        // If we didn't request fullscreen layout, but we still got it because of the
+        // mForceWindowDrawsStatusBarBackground flag, also consume top inset.
+        boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
+                && (sysUiVisibility & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
+                && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
+                && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
+                && mForceWindowDrawsStatusBarBackground
+                && mLastTopInset != 0;
+
+        int consumedTop = consumingStatusBar ? mLastTopInset : 0;
         int consumedRight = consumingNavBar ? mLastRightInset : 0;
         int consumedBottom = consumingNavBar ? mLastBottomInset : 0;
 
         if (mContentRoot != null
                 && mContentRoot.getLayoutParams() instanceof MarginLayoutParams) {
             MarginLayoutParams lp = (MarginLayoutParams) mContentRoot.getLayoutParams();
-            if (lp.rightMargin != consumedRight || lp.bottomMargin != consumedBottom) {
+            if (lp.topMargin != consumedTop || lp.rightMargin != consumedRight
+                    || lp.bottomMargin != consumedBottom) {
+                lp.topMargin = consumedTop;
                 lp.rightMargin = consumedRight;
                 lp.bottomMargin = consumedBottom;
                 mContentRoot.setLayoutParams(lp);
@@ -1020,7 +1035,7 @@
             if (insets != null) {
                 insets = insets.replaceSystemWindowInsets(
                         insets.getSystemWindowInsetLeft(),
-                        insets.getSystemWindowInsetTop(),
+                        insets.getSystemWindowInsetTop() - consumedTop,
                         insets.getSystemWindowInsetRight() - consumedRight,
                         insets.getSystemWindowInsetBottom() - consumedBottom);
             }
@@ -1706,7 +1721,9 @@
             mDecorCaptionView.addView(root,
                     new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
         } else {
-            addView(root, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+
+            // Put it below the color views.
+            addView(root, 0, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
         }
         mContentRoot = (ViewGroup) root;
         initializeElevation();
@@ -1714,8 +1731,13 @@
 
     private void loadBackgroundDrawablesIfNeeded() {
         if (mResizingBackgroundDrawable == null) {
-            mResizingBackgroundDrawable = getResizingBackgroundDrawable(
+            mResizingBackgroundDrawable = getResizingBackgroundDrawable(getContext(),
                     mWindow.mBackgroundResource, mWindow.mBackgroundFallbackResource);
+            if (mResizingBackgroundDrawable == null) {
+                // We shouldn't really get here as the background fallback should be always
+                // available since it is defaulted by the system.
+                Log.w(mLogTag, "Failed to find background drawable for PhoneWindow=" + mWindow);
+            }
         }
         if (mCaptionBackgroundDrawable == null) {
             mCaptionBackgroundDrawable = getContext().getDrawable(
@@ -1813,9 +1835,8 @@
      * Returns the color used to fill areas the app has not rendered content to yet when the
      * user is resizing the window of an activity in multi-window mode.
      */
-    private Drawable getResizingBackgroundDrawable(int backgroundRes, int backgroundFallbackRes) {
-        final Context context = getContext();
-
+    public static Drawable getResizingBackgroundDrawable(Context context, int backgroundRes,
+            int backgroundFallbackRes) {
         if (backgroundRes != 0) {
             final Drawable drawable = context.getDrawable(backgroundRes);
             if (drawable != null) {
@@ -1829,10 +1850,6 @@
                 return fallbackDrawable;
             }
         }
-
-        // We shouldn't really get here as the background fallback should be always available since
-        // it is defaulted by the system.
-        Log.w(mLogTag, "Failed to find background drawable for PhoneWindow=" + mWindow);
         return null;
     }
 
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index 597c522..84d0fc7 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -136,8 +136,7 @@
                     / (mFirstSplitTarget.position - getStartInset());
         } else if (position > mLastSplitTarget.position) {
             return (float) (position - mLastSplitTarget.position)
-                    / (mDismissEndTarget.position - getEndInset()
-                            - mLastSplitTarget.position - mDividerSize);
+                    / (mDismissEndTarget.position - mLastSplitTarget.position - mDividerSize);
         }
         return 0f;
     }
@@ -222,7 +221,8 @@
                 addMiddleTarget(isHorizontalDivision);
                 break;
         }
-        mTargets.add(new SnapTarget(dividerMax, SnapTarget.FLAG_DISMISS_END, 0.35f));
+        int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
+        mTargets.add(new SnapTarget(dividerMax - navBarSize, SnapTarget.FLAG_DISMISS_END, 0.35f));
     }
 
     private void addFixedDivisionTargets(boolean isHorizontalDivision) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 6e374e2..08d4fba 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.statusbar;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.service.notification.StatusBarNotification;
 
@@ -31,7 +32,23 @@
     void animateExpandNotificationsPanel();
     void animateExpandSettingsPanel(String subPanel);
     void animateCollapsePanels();
-    void setSystemUiVisibility(int vis, int mask);
+
+    /**
+     * Notifies the status bar of a System UI visibility flag change.
+     *
+     * @param vis the visibility flags except SYSTEM_UI_FLAG_LIGHT_STATUS_BAR which will be reported
+     *            separately in fullscreenStackVis and dockedStackVis
+     * @param fullscreenStackVis the flags which only apply in the region of the fullscreen stack,
+     *                           which is currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+     * @param dockedStackVis the flags that only apply in the region of the docked stack, which is
+     *                       currently only SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+     * @param mask which flags to change
+     * @param fullscreenBounds the current bounds of the fullscreen stack, in screen coordinates
+     * @param dockedBounds the current bounds of the docked stack, in screen coordinates
+     */
+    void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
+            in Rect fullscreenBounds, in Rect dockedBounds);
+
     void topAppWindowChanged(boolean menuVisible);
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index bec18ec..8acf5d3 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -17,6 +17,7 @@
 package com.android.internal.statusbar;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.service.notification.StatusBarNotification;
 
@@ -37,7 +38,6 @@
     void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
     void setIconVisibility(String slot, boolean visible);
     void removeIcon(String slot);
-    void topAppWindowChanged(boolean menuVisible);
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
     void expandSettingsPanel(String subPanel);
@@ -47,7 +47,8 @@
     // You need the STATUS_BAR_SERVICE permission
     void registerStatusBar(IStatusBar callbacks, out List<String> iconSlots,
             out List<StatusBarIcon> iconList,
-            out int[] switches, out List<IBinder> binders);
+            out int[] switches, out List<IBinder> binders, out Rect fullscreenStackBounds,
+            out Rect dockedStackBounds);
     void onPanelRevealed(boolean clearNotificationEffects, int numItems);
     void onPanelHidden();
     // Mark current notifications as "seen" and stop ringing, vibrating, blinking.
diff --git a/core/java/com/android/internal/util/LineBreakBufferedWriter.java b/core/java/com/android/internal/util/LineBreakBufferedWriter.java
index f831e7a..552a93f 100644
--- a/core/java/com/android/internal/util/LineBreakBufferedWriter.java
+++ b/core/java/com/android/internal/util/LineBreakBufferedWriter.java
@@ -96,7 +96,7 @@
 
     @Override
     public void write(int c) {
-        if (bufferIndex < bufferSize) {
+        if (bufferIndex < buffer.length) {
             buffer[bufferIndex] = (char)c;
             bufferIndex++;
             if ((char)c == '\n') {
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 2f26e92..53cb56e 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -104,12 +104,24 @@
      * instance, but not involving any parameters to the calling method.
      *
      * @param expression a boolean expression
+     * @param message exception message
+     * @throws IllegalStateException if {@code expression} is false
+     */
+    public static void checkState(final boolean expression, String message) {
+        if (!expression) {
+            throw new IllegalStateException(message);
+        }
+    }
+
+    /**
+     * Ensures the truth of an expression involving the state of the calling
+     * instance, but not involving any parameters to the calling method.
+     *
+     * @param expression a boolean expression
      * @throws IllegalStateException if {@code expression} is false
      */
     public static void checkState(final boolean expression) {
-        if (!expression) {
-            throw new IllegalStateException();
-        }
+        checkState(expression, null);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/AlertDialogLayout.java b/core/java/com/android/internal/widget/AlertDialogLayout.java
index cc0db51..891c920 100644
--- a/core/java/com/android/internal/widget/AlertDialogLayout.java
+++ b/core/java/com/android/internal/widget/AlertDialogLayout.java
@@ -17,7 +17,6 @@
 package com.android.internal.widget;
 
 import android.annotation.AttrRes;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StyleRes;
 import android.content.Context;
@@ -107,14 +106,7 @@
 
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
-        // Treat all panel widths as MATCH_PARENT
-        // by translating AT_MOST to EXACTLY.
         final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        if (widthMode == MeasureSpec.AT_MOST) {
-            final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
-        }
 
         int childState = 0;
         int usedHeight = getPaddingTop() + getPaddingBottom();
@@ -204,15 +196,52 @@
                 maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
             }
         }
+
         maxWidth += getPaddingLeft() + getPaddingRight();
 
         final int widthSizeAndState = resolveSizeAndState(maxWidth, widthMeasureSpec, childState);
         final int heightSizeAndState = resolveSizeAndState(usedHeight, heightMeasureSpec, 0);
         setMeasuredDimension(widthSizeAndState, heightSizeAndState);
+
+        // If the children weren't already measured EXACTLY, we need to run
+        // another measure pass to for MATCH_PARENT widths.
+        if (widthMode != MeasureSpec.EXACTLY) {
+            forceUniformWidth(count, heightMeasureSpec);
+        }
+
         return true;
     }
 
     /**
+     * Remeasures child views to exactly match the layout's measured width.
+     *
+     * @param count the number of child views
+     * @param heightMeasureSpec the original height measure spec
+     */
+    private void forceUniformWidth(int count, int heightMeasureSpec) {
+        // Pretend that the linear layout has an exact size.
+        final int uniformMeasureSpec = MeasureSpec.makeMeasureSpec(
+                getMeasuredWidth(), MeasureSpec.EXACTLY);
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if (lp.width == LayoutParams.MATCH_PARENT) {
+                    // Temporarily force children to reuse their old measured
+                    // height.
+                    final int oldHeight = lp.height;
+                    lp.height = child.getMeasuredHeight();
+
+                    // Remeasure with new dimensions.
+                    measureChildWithMargins(child, uniformMeasureSpec, 0, heightMeasureSpec, 0);
+                    lp.height = oldHeight;
+                }
+            }
+        }
+    }
+
+    /**
      * Attempts to resolve the minimum height of a view.
      * <p>
      * If the view doesn't have a minimum height set and only contains a single
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index e239852..cbc735f 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -283,6 +283,15 @@
         getTrustManager().reportUnlockAttempt(true /* authenticated */, userId);
     }
 
+    public int getCurrentFailedPasswordAttempts(int userId) {
+        return getDevicePolicyManager().getCurrentFailedPasswordAttempts(userId);
+    }
+
+    public int getMaximumFailedPasswordsForWipe(int userId) {
+        return getDevicePolicyManager().getMaximumFailedPasswordsForWipe(
+                null /* componentName */, userId);
+    }
+
     /**
      * Check to see if a pattern matches the saved pattern.
      * If pattern matches, return an opaque attestation that the challenge
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 92d5aea..ab75b7c 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -19,10 +19,10 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.content.pm.IPackageManager;
 import android.os.Build;
 import android.os.DropBoxManager;
+import android.os.Environment;
 import android.os.FileObserver;
 import android.os.FileUtils;
 import android.os.RecoverySystem;
@@ -30,10 +30,25 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.provider.Downloads;
+import android.util.AtomicFile;
 import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.util.FastXmlSerializer;
+import com.android.internal.util.XmlUtils;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 /**
  * Performs a number of miscellaneous, non-system-critical actions
@@ -60,6 +75,10 @@
     // Keep a reference to the observer so the finalizer doesn't disable it.
     private static FileObserver sTombstoneObserver = null;
 
+    private static final String LOG_FILES_FILE = "log-files.xml";
+    private static final AtomicFile sFile = new AtomicFile(new File(
+            Environment.getDataSystemDirectory(), LOG_FILES_FILE));
+
     @Override
     public void onReceive(final Context context, Intent intent) {
         // Log boot events in the background to avoid blocking the main thread with I/O
@@ -95,7 +114,6 @@
 
     private void logBootEvents(Context ctx) throws IOException {
         final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
-        final SharedPreferences prefs = ctx.getSharedPreferences("log_files", Context.MODE_PRIVATE);
         final String headers = new StringBuilder(512)
             .append("Build: ").append(Build.FINGERPRINT).append("\n")
             .append("Hardware: ").append(Build.BOARD).append("\n")
@@ -122,9 +140,11 @@
                 .toString();
         }
 
+        HashMap<String, Long> timestamps = readTimestamps();
+
         if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
             if ("encrypted".equals(SystemProperties.get("ro.crypto.state"))
-                && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))){
+                && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))) {
                 // Encrypted, first boot to get PIN/pattern/password so data is tmpfs
                 // Don't set ro.runtime.firstboot so that we will do this again
                 // when data is properly mounted
@@ -135,17 +155,16 @@
             if (db != null) db.addText("SYSTEM_BOOT", headers);
 
             // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
-            addFileWithFootersToDropBox(db, prefs, headers, lastKmsgFooter,
+            addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter,
                     "/proc/last_kmsg", -LOG_SIZE, "SYSTEM_LAST_KMSG");
-            addFileWithFootersToDropBox(db, prefs, headers, lastKmsgFooter,
-                    "/sys/fs/pstore/console-ramoops", -LOG_SIZE,
-                    "SYSTEM_LAST_KMSG");
-            addFileToDropBox(db, prefs, headers, "/cache/recovery/log",
-                    -LOG_SIZE, "SYSTEM_RECOVERY_LOG");
-            addFileToDropBox(db, prefs, headers, "/cache/recovery/last_kmsg",
+            addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter,
+                    "/sys/fs/pstore/console-ramoops", -LOG_SIZE, "SYSTEM_LAST_KMSG");
+            addFileToDropBox(db, timestamps, headers, "/cache/recovery/log", -LOG_SIZE,
+                    "SYSTEM_RECOVERY_LOG");
+            addFileToDropBox(db, timestamps, headers, "/cache/recovery/last_kmsg",
                     -LOG_SIZE, "SYSTEM_RECOVERY_KMSG");
-            addAuditErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_AUDIT");
-            addFsckErrorsToDropBox(db, prefs, headers, -LOG_SIZE, "SYSTEM_FSCK");
+            addAuditErrorsToDropBox(db, timestamps, headers, -LOG_SIZE, "SYSTEM_AUDIT");
+            addFsckErrorsToDropBox(db, timestamps, headers, -LOG_SIZE, "SYSTEM_FSCK");
         } else {
             if (db != null) db.addText("SYSTEM_RESTART", headers);
         }
@@ -154,24 +173,29 @@
         File[] tombstoneFiles = TOMBSTONE_DIR.listFiles();
         for (int i = 0; tombstoneFiles != null && i < tombstoneFiles.length; i++) {
             if (tombstoneFiles[i].isFile()) {
-                addFileToDropBox(db, prefs, headers, tombstoneFiles[i].getPath(),
+                addFileToDropBox(db, timestamps, headers, tombstoneFiles[i].getPath(),
                         LOG_SIZE, "SYSTEM_TOMBSTONE");
             }
         }
 
+        writeTimestamps(timestamps);
+
         // Start watching for new tombstone files; will record them as they occur.
         // This gets registered with the singleton file observer thread.
         sTombstoneObserver = new FileObserver(TOMBSTONE_DIR.getPath(), FileObserver.CLOSE_WRITE) {
             @Override
             public void onEvent(int event, String path) {
+                HashMap<String, Long> timestamps = readTimestamps();
                 try {
                     File file = new File(TOMBSTONE_DIR, path);
                     if (file.isFile()) {
-                        addFileToDropBox(db, prefs, headers, file.getPath(), LOG_SIZE, "SYSTEM_TOMBSTONE");
+                        addFileToDropBox(db, timestamps, headers, file.getPath(), LOG_SIZE,
+                                "SYSTEM_TOMBSTONE");
                     }
                 } catch (IOException e) {
                     Slog.e(TAG, "Can't log tombstone", e);
                 }
+                writeTimestamps(timestamps);
             }
         };
 
@@ -179,14 +203,13 @@
     }
 
     private static void addFileToDropBox(
-            DropBoxManager db, SharedPreferences prefs,
+            DropBoxManager db, HashMap<String, Long> timestamps,
             String headers, String filename, int maxSize, String tag) throws IOException {
-        addFileWithFootersToDropBox(db, prefs, headers, "", filename, maxSize,
-                tag);
+        addFileWithFootersToDropBox(db, timestamps, headers, "", filename, maxSize, tag);
     }
 
     private static void addFileWithFootersToDropBox(
-            DropBoxManager db, SharedPreferences prefs,
+            DropBoxManager db, HashMap<String, Long> timestamps,
             String headers, String footers, String filename, int maxSize,
             String tag) throws IOException {
         if (db == null || !db.isTagEnabled(tag)) return;  // Logging disabled
@@ -195,20 +218,20 @@
         long fileTime = file.lastModified();
         if (fileTime <= 0) return;  // File does not exist
 
-        if (prefs != null) {
-            long lastTime = prefs.getLong(filename, 0);
-            if (lastTime == fileTime) return;  // Already logged this particular file
-            // TODO: move all these SharedPreferences Editor commits
-            // outside this function to the end of logBootEvents
-            prefs.edit().putLong(filename, fileTime).apply();
+        if (timestamps.containsKey(filename) && timestamps.get(filename) == fileTime) {
+            return;  // Already logged this particular file
         }
 
+        timestamps.put(filename, fileTime);
+
         Slog.i(TAG, "Copying " + filename + " to DropBox (" + tag + ")");
-        db.addText(tag, headers + FileUtils.readTextFile(file, maxSize, "[[TRUNCATED]]\n") + footers);
+        db.addText(tag, headers + FileUtils.readTextFile(file, maxSize, "[[TRUNCATED]]\n") +
+                footers);
     }
 
-    private static void addAuditErrorsToDropBox(DropBoxManager db,  SharedPreferences prefs,
-            String headers, int maxSize, String tag) throws IOException {
+    private static void addAuditErrorsToDropBox(DropBoxManager db,
+            HashMap<String, Long> timestamps, String headers, int maxSize, String tag)
+            throws IOException {
         if (db == null || !db.isTagEnabled(tag)) return;  // Logging disabled
         Slog.i(TAG, "Copying audit failures to DropBox");
 
@@ -221,14 +244,12 @@
 
         if (fileTime <= 0) return;  // File does not exist
 
-        if (prefs != null) {
-            long lastTime = prefs.getLong(tag, 0);
-            if (lastTime == fileTime) return;  // Already logged this particular file
-            // TODO: move all these SharedPreferences Editor commits
-            // outside this function to the end of logBootEvents
-            prefs.edit().putLong(tag, fileTime).apply();
+        if (timestamps.containsKey(tag) && timestamps.get(tag) == fileTime) {
+            return;  // Already logged this particular file
         }
 
+        timestamps.put(tag, fileTime);
+
         String log = FileUtils.readTextFile(file, maxSize, "[[TRUNCATED]]\n");
         StringBuilder sb = new StringBuilder();
         for (String line : log.split("\n")) {
@@ -240,8 +261,9 @@
         db.addText(tag, headers + sb.toString());
     }
 
-    private static void addFsckErrorsToDropBox(DropBoxManager db,  SharedPreferences prefs,
-            String headers, int maxSize, String tag) throws IOException {
+    private static void addFsckErrorsToDropBox(DropBoxManager db,
+            HashMap<String, Long> timestamps, String headers, int maxSize, String tag)
+            throws IOException {
         boolean upload_needed = false;
         if (db == null || !db.isTagEnabled(tag)) return;  // Logging disabled
         Slog.i(TAG, "Checking for fsck errors");
@@ -260,10 +282,103 @@
         }
 
         if (upload_needed) {
-            addFileToDropBox(db, prefs, headers, "/dev/fscklogs/log", maxSize, tag);
+            addFileToDropBox(db, timestamps, headers, "/dev/fscklogs/log", maxSize, tag);
         }
 
         // Remove the file so we don't re-upload if the runtime restarts.
         file.delete();
     }
+
+    private static HashMap<String, Long> readTimestamps() {
+        synchronized (sFile) {
+            HashMap<String, Long> timestamps = new HashMap<String, Long>();
+            boolean success = false;
+            try (final FileInputStream stream = sFile.openRead()) {
+                XmlPullParser parser = Xml.newPullParser();
+                parser.setInput(stream, StandardCharsets.UTF_8.name());
+
+                int type;
+                while ((type = parser.next()) != XmlPullParser.START_TAG
+                        && type != XmlPullParser.END_DOCUMENT) {
+                    ;
+                }
+
+                if (type != XmlPullParser.START_TAG) {
+                    throw new IllegalStateException("no start tag found");
+                }
+
+                int outerDepth = parser.getDepth();  // Skip the outer <log-files> tag.
+                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                        && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+                    if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                        continue;
+                    }
+
+                    String tagName = parser.getName();
+                    if (tagName.equals("log")) {
+                        final String filename = parser.getAttributeValue(null, "filename");
+                        final long timestamp = Long.valueOf(parser.getAttributeValue(
+                                    null, "timestamp"));
+                        timestamps.put(filename, timestamp);
+                    } else {
+                        Slog.w(TAG, "Unknown tag: " + parser.getName());
+                        XmlUtils.skipCurrentTag(parser);
+                    }
+                }
+                success = true;
+            } catch (FileNotFoundException e) {
+                Slog.i(TAG, "No existing last log timestamp file " + sFile.getBaseFile() +
+                        "; starting empty");
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed parsing " + e);
+            } catch (IllegalStateException e) {
+                Slog.w(TAG, "Failed parsing " + e);
+            } catch (NullPointerException e) {
+                Slog.w(TAG, "Failed parsing " + e);
+            } catch (XmlPullParserException e) {
+                Slog.w(TAG, "Failed parsing " + e);
+            } finally {
+                if (!success) {
+                    timestamps.clear();
+                }
+            }
+            return timestamps;
+        }
+    }
+
+    private void writeTimestamps(HashMap<String, Long> timestamps) {
+        synchronized (sFile) {
+            final FileOutputStream stream;
+            try {
+                stream = sFile.startWrite();
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to write timestamp file: " + e);
+                return;
+            }
+
+            try {
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(stream, StandardCharsets.UTF_8.name());
+                out.startDocument(null, true);
+                out.startTag(null, "log-files");
+
+                Iterator<String> itor = timestamps.keySet().iterator();
+                while (itor.hasNext()) {
+                    String filename = itor.next();
+                    out.startTag(null, "log");
+                    out.attribute(null, "filename", filename);
+                    out.attribute(null, "timestamp", timestamps.get(filename).toString());
+                    out.endTag(null, "log");
+                }
+
+                out.endTag(null, "log-files");
+                out.endDocument();
+
+                sFile.finishWrite(stream);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to write timestamp file, using the backup: " + e);
+                sFile.failWrite(stream);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
index 0449340..1b40492 100644
--- a/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountSyncSettingsBackupHelper.java
@@ -16,10 +16,6 @@
 
 package com.android.server.backup;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.app.backup.BackupDataInputStream;
@@ -28,14 +24,21 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SyncAdapterType;
+import android.os.Environment;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
 import java.io.BufferedOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.EOFException;
+import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.security.MessageDigest;
@@ -73,6 +76,8 @@
     private static final String KEY_AUTHORITY_NAME = "name";
     private static final String KEY_AUTHORITY_SYNC_STATE = "syncState";
     private static final String KEY_AUTHORITY_SYNC_ENABLED = "syncEnabled";
+    private static final String STASH_FILE = Environment.getDataDirectory()
+            + "/backup/unadded_account_syncsettings.json";
 
     private Context mContext;
     private AccountManager mAccountManager;
@@ -256,41 +261,99 @@
             }
 
             try {
-                HashSet<Account> currentAccounts = getAccountsHashSet();
-                for (int i = 0; i < accountJSONArray.length(); i++) {
-                    JSONObject accountJSON = (JSONObject) accountJSONArray.get(i);
-                    String accountName = accountJSON.getString(KEY_ACCOUNT_NAME);
-                    String accountType = accountJSON.getString(KEY_ACCOUNT_TYPE);
-
-                    Account account = new Account(accountName, accountType);
-
-                    // Check if the account already exists. Accounts that don't exist on the device
-                    // yet won't be restored.
-                    if (currentAccounts.contains(account)) {
-                        restoreExistingAccountSyncSettingsFromJSON(accountJSON);
-                    } else {
-                        // TODO:
-                        // Stash the data to a file that the SyncManager can read from to restore
-                        // settings at a later date.
-                    }
-                }
+                restoreFromJsonArray(accountJSONArray);
             } finally {
                 // Set the master sync preference to the value from the backup set.
                 ContentResolver.setMasterSyncAutomatically(masterSyncEnabled);
             }
-
             Log.i(TAG, "Restore successful.");
         } catch (IOException | JSONException e) {
             Log.e(TAG, "Couldn't restore account sync settings\n" + e);
         }
     }
 
+    private void restoreFromJsonArray(JSONArray accountJSONArray)
+            throws JSONException {
+        HashSet<Account> currentAccounts = getAccounts();
+        JSONArray unaddedAccountsJSONArray = new JSONArray();
+        for (int i = 0; i < accountJSONArray.length(); i++) {
+            JSONObject accountJSON = (JSONObject) accountJSONArray.get(i);
+            String accountName = accountJSON.getString(KEY_ACCOUNT_NAME);
+            String accountType = accountJSON.getString(KEY_ACCOUNT_TYPE);
+
+            Account account = null;
+            try {
+                account = new Account(accountName, accountType);
+            } catch (IllegalArgumentException iae) {
+                continue;
+            }
+
+            // Check if the account already exists. Accounts that don't exist on the device
+            // yet won't be restored.
+            if (currentAccounts.contains(account)) {
+                if (DEBUG) Log.i(TAG, "Restoring Sync Settings for" + accountName);
+                restoreExistingAccountSyncSettingsFromJSON(accountJSON);
+            } else {
+                unaddedAccountsJSONArray.put(accountJSON);
+            }
+        }
+
+        if (unaddedAccountsJSONArray.length() > 0) {
+            try (FileOutputStream fOutput = new FileOutputStream(STASH_FILE)) {
+                String jsonString = unaddedAccountsJSONArray.toString();
+                DataOutputStream out = new DataOutputStream(fOutput);
+                out.writeUTF(jsonString);
+            } catch (IOException ioe) {
+                // Error in writing to stash file
+                Log.e(TAG, "unable to write the sync settings to the stash file", ioe);
+            }
+        } else {
+            File stashFile = new File(STASH_FILE);
+            if (stashFile.exists()) stashFile.delete();
+        }
+    }
+
+    /**
+     * Restore SyncSettings for all existing accounts from a stashed backup-set
+     */
+    private void accountAddedInternal() {
+        String jsonString;
+
+        try (FileInputStream fIn = new FileInputStream(new File(STASH_FILE))) {
+            DataInputStream in = new DataInputStream(fIn);
+            jsonString = in.readUTF();
+        } catch (FileNotFoundException fnfe) {
+            // This is expected to happen when there is no accounts info stashed
+            if (DEBUG) Log.d(TAG, "unable to find the stash file", fnfe);
+            return;
+        } catch (IOException ioe) {
+            if (DEBUG) Log.d(TAG, "could not read sync settings from stash file", ioe);
+            return;
+        }
+
+        try {
+            JSONArray unaddedAccountsJSONArray = new JSONArray(jsonString);
+            restoreFromJsonArray(unaddedAccountsJSONArray);
+        } catch (JSONException jse) {
+            // Malformed jsonString
+            Log.e(TAG, "there was an error with the stashed sync settings", jse);
+        }
+    }
+
+    /**
+     * Restore SyncSettings for all existing accounts from a stashed backup-set
+     */
+    public static void accountAdded(Context context) {
+        AccountSyncSettingsBackupHelper helper = new AccountSyncSettingsBackupHelper(context);
+        helper.accountAddedInternal();
+    }
+
     /**
      * Helper method - fetch accounts and return them as a HashSet.
      *
      * @return Accounts in a HashSet.
      */
-    private HashSet<Account> getAccountsHashSet() {
+    private HashSet<Account> getAccounts() {
         Account[] accounts = mAccountManager.getAccounts();
         HashSet<Account> accountHashSet = new HashSet<Account>();
         for (Account account : accounts) {
@@ -359,4 +422,4 @@
     public void writeNewStateDescription(ParcelFileDescriptor newState) {
 
     }
-}
+}
\ No newline at end of file
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 92f7812..8b248b0 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -505,12 +505,6 @@
             bitmapCreateFlags, ninePatchChunk, ninePatchInsets, -1);
 }
 
-// Need to buffer enough input to be able to rewind as much as might be read by a decoder
-// trying to determine the stream's format. Currently the most is 64, read by
-// SkWebpCodec.
-// FIXME: Get this number from SkCodec
-#define BYTES_TO_BUFFER 64
-
 static jobject nativeDecodeStream(JNIEnv* env, jobject clazz, jobject is, jbyteArray storage,
         jobject padding, jobject options) {
 
@@ -519,7 +513,7 @@
 
     if (stream.get()) {
         std::unique_ptr<SkStreamRewindable> bufferedStream(
-                SkFrontBufferedStream::Create(stream.release(), BYTES_TO_BUFFER));
+                SkFrontBufferedStream::Create(stream.release(), SkCodec::MinBufferedBytesNeeded()));
         SkASSERT(bufferedStream.get() != NULL);
         bitmap = doDecode(env, bufferedStream.release(), padding, options);
     }
@@ -565,7 +559,7 @@
     // ensures that SkImageDecoder::Factory never rewinds beyond the
     // current position of the file descriptor.
     std::unique_ptr<SkStreamRewindable> stream(SkFrontBufferedStream::Create(fileStream.release(),
-            BYTES_TO_BUFFER));
+            SkCodec::MinBufferedBytesNeeded()));
 
     return doDecode(env, stream.release(), padding, bitmapFactoryOptions);
 }
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 7c8dbe8..2e974a3 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -20,11 +20,13 @@
 #include <core_jni_helpers.h>
 
 #include "SkData.h"
+#include "SkFontMgr.h"
 #include "SkRefCnt.h"
 #include "SkTypeface.h"
 #include "GraphicsJNI.h"
 #include <ScopedPrimitiveArray.h>
 #include <ScopedUtfChars.h>
+#include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_util_AssetManager.h>
 #include <androidfw/AssetManager.h>
 #include "Utils.h"
@@ -33,6 +35,8 @@
 #include <minikin/FontFamily.h>
 #include "MinikinSkia.h"
 
+#include <memory>
+
 namespace android {
 
 static jlong FontFamily_create(JNIEnv* env, jobject clazz, jstring lang, jint variant) {
@@ -69,13 +73,89 @@
     return addSkTypeface(fontFamily, face);
 }
 
+static struct {
+    jmethodID mGet;
+    jmethodID mSize;
+} gListClassInfo;
+
+static struct {
+    jfieldID mTag;
+    jfieldID mStyleValue;
+} gAxisClassInfo;
+
+static void release_global_ref(const void* /*data*/, void* context) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    bool needToAttach = (env == NULL);
+    if (needToAttach) {
+        JavaVMAttachArgs args;
+        args.version = JNI_VERSION_1_4;
+        args.name = "release_font_data";
+        args.group = NULL;
+        jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args);
+        if (result != JNI_OK) {
+            ALOGE("failed to attach to thread to release global ref.");
+            return;
+        }
+    }
+
+    jobject obj = reinterpret_cast<jobject>(context);
+    env->DeleteGlobalRef(obj);
+
+    if (needToAttach) {
+       AndroidRuntime::getJavaVM()->DetachCurrentThread();
+    }
+}
+
 static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr,
-        jstring path, jint ttcIndex, jint weight, jboolean isItalic) {
-    NPE_CHECK_RETURN_ZERO(env, path);
-    ScopedUtfChars str(env, path);
-    SkTypeface* face = SkTypeface::CreateFromFile(str.c_str(), ttcIndex);
+        jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
+    NPE_CHECK_RETURN_ZERO(env, font);
+
+    // Declare axis native type.
+    std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes;
+    int skiaAxesLength = 0;
+    if (listOfAxis) {
+        jint listSize = env->CallIntMethod(listOfAxis, gListClassInfo.mSize);
+
+        skiaAxes.reset(new SkFontMgr::FontParameters::Axis[listSize]);
+        skiaAxesLength = listSize;
+        for (jint i = 0; i < listSize; ++i) {
+            jobject axisObject = env->CallObjectMethod(listOfAxis, gListClassInfo.mGet, i);
+            if (!axisObject) {
+                skiaAxes[i].fTag = 0;
+                skiaAxes[i].fStyleValue = 0;
+                continue;
+            }
+
+            jint tag = env->GetIntField(axisObject, gAxisClassInfo.mTag);
+            jfloat stylevalue = env->GetFloatField(axisObject, gAxisClassInfo.mStyleValue);
+            skiaAxes[i].fTag = tag;
+            skiaAxes[i].fStyleValue = SkFloatToScalar(stylevalue);
+        }
+    }
+
+    void* fontPtr = env->GetDirectBufferAddress(font);
+    if (fontPtr == NULL) {
+        ALOGE("addFont failed to create font, buffer invalid");
+        return false;
+    }
+    jlong fontSize = env->GetDirectBufferCapacity(font);
+    if (fontSize < 0) {
+        ALOGE("addFont failed to create font, buffer size invalid");
+        return false;
+    }
+    jobject fontRef = MakeGlobalRefOrDie(env, font);
+    SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize,
+            release_global_ref, reinterpret_cast<void*>(fontRef)));
+    std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data));
+
+    SkFontMgr::FontParameters params;
+    params.setCollectionIndex(ttcIndex);
+    params.setAxes(skiaAxes.get(), skiaAxesLength);
+
+    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+    SkTypeface* face = fm->createFromStream(fontData.release(), params);
     if (face == NULL) {
-        ALOGE("addFont failed to create font %s", str.c_str());
+        ALOGE("addFont failed to create font, invalid request");
         return false;
     }
     FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr);
@@ -129,15 +209,26 @@
     { "nCreateFamily",         "(Ljava/lang/String;I)J", (void*)FontFamily_create },
     { "nUnrefFamily",          "(J)V", (void*)FontFamily_unref },
     { "nAddFont",              "(JLjava/lang/String;I)Z", (void*)FontFamily_addFont },
-    { "nAddFontWeightStyle",   "(JLjava/lang/String;IIZ)Z", (void*)FontFamily_addFontWeightStyle },
+    { "nAddFontWeightStyle",   "(JLjava/nio/ByteBuffer;ILjava/util/List;IZ)Z",
+            (void*)FontFamily_addFontWeightStyle },
     { "nAddFontFromAsset",     "(JLandroid/content/res/AssetManager;Ljava/lang/String;)Z",
-                                           (void*)FontFamily_addFontFromAsset },
+            (void*)FontFamily_addFontFromAsset },
 };
 
 int register_android_graphics_FontFamily(JNIEnv* env)
 {
-    return RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods,
-                                NELEM(gFontFamilyMethods));
+    int err = RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods,
+            NELEM(gFontFamilyMethods));
+
+    jclass listClass = FindClassOrDie(env, "java/util/List");
+    gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
+    gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
+
+    jclass axisClass = FindClassOrDie(env, "android/graphics/FontListParser$Axis");
+    gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "tag", "I");
+    gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "styleValue", "F");
+
+    return err;
 }
 
 }
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index bcd0b60..0c30fdc 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -212,17 +212,16 @@
 
     android::Parcel* p = android::parcelForJavaObject(env, parcel);
 
-    const size_t size = p->readInt32();
-    const void* regionData = p->readInplace(size);
-    if (regionData == nullptr) {
+    std::vector<int32_t> rects;
+    p->readInt32Vector(&rects);
+
+    if ((rects.size() % 4) != 0) {
         return 0;
     }
 
     SkRegion* region = new SkRegion;
-    size_t actualSize = region->readFromMemory(regionData, size);
-    if (size != actualSize) {
-        delete region;
-        return 0;
+    for (size_t x = 0; x + 4 <= rects.size(); x += 4) {
+        region->op(rects[x], rects[x+1], rects[x+2], rects[x+3], SkRegion::kUnion_Op);
     }
 
     return reinterpret_cast<jlong>(region);
@@ -237,19 +236,18 @@
 
     android::Parcel* p = android::parcelForJavaObject(env, parcel);
 
-    const size_t size = region->writeToMemory(nullptr);
-    p->writeInt32(size);
-    void* dst = p->writeInplace(size);
-    if (dst == nullptr) {
-        ALOGE("Region.writeToParcel could not write %zi bytes", size);
-        return JNI_FALSE;
-    }
-    const size_t sizeWritten = region->writeToMemory(dst);
-    if (sizeWritten != size) {
-        ALOGE("SkRegion::writeToMemory should have written %zi bytes but wrote %zi",
-                size, sizeWritten);
+    std::vector<int32_t> rects;
+    SkRegion::Iterator it(*region);
+    while (!it.done()) {
+        const SkIRect& r = it.rect();
+        rects.push_back(r.fLeft);
+        rects.push_back(r.fTop);
+        rects.push_back(r.fRight);
+        rects.push_back(r.fBottom);
+        it.next();
     }
 
+    p->writeInt32Vector(rects);
     return JNI_TRUE;
 }
 
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 2507e4d..de32dd9 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -1,5 +1,4 @@
 #include "GraphicsJNI.h"
-#include "SkComposeShader.h"
 #include "SkGradientShader.h"
 #include "SkShader.h"
 #include "SkXfermode.h"
@@ -232,7 +231,7 @@
     SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
     SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
     SkXfermode* mode = reinterpret_cast<SkXfermode *>(modeHandle);
-    SkShader* shader = new SkComposeShader(shaderA, shaderB, mode);
+    SkShader* shader = SkShader::CreateComposeShader(shaderA, shaderB, mode);
     return reinterpret_cast<jlong>(shader);
 }
 
@@ -243,7 +242,7 @@
     SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
     SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(xfermodeHandle);
     SkAutoTUnref<SkXfermode> xfermode(SkXfermode::Create(mode));
-    SkShader* shader = new SkComposeShader(shaderA, shaderB, xfermode.get());
+    SkShader* shader = SkShader::CreateComposeShader(shaderA, shaderB, xfermode.get());
     return reinterpret_cast<jlong>(shader);
 }
 
diff --git a/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp b/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
index 7a3c598..14badb7 100644
--- a/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
+++ b/core/jni/android_graphics_drawable_AnimatedVectorDrawable.cpp
@@ -43,12 +43,13 @@
     return env;
 }
 
-static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener) {
+static AnimationListener* createAnimationListener(JNIEnv* env, jobject finishListener, jint id) {
     class AnimationListenerBridge : public AnimationListener {
     public:
-        AnimationListenerBridge(JNIEnv* env, jobject finishListener) {
+        AnimationListenerBridge(JNIEnv* env, jobject finishListener, jint id) {
             mFinishListener = env->NewGlobalRef(finishListener);
             env->GetJavaVM(&mJvm);
+            mId = id;
         }
 
         virtual ~AnimationListenerBridge() {
@@ -63,7 +64,7 @@
             env->CallStaticVoidMethod(
                     gVectorDrawableAnimatorClassInfo.clazz,
                     gVectorDrawableAnimatorClassInfo.callOnFinished,
-                    mFinishListener);
+                    mFinishListener, mId);
             releaseJavaObject();
         }
 
@@ -76,8 +77,9 @@
 
         JavaVM* mJvm;
         jobject mFinishListener;
+        jint mId;
     };
-    return new AnimationListenerBridge(env, finishListener);
+    return new AnimationListenerBridge(env, finishListener, id);
 }
 
 static void addAnimator(JNIEnv*, jobject, jlong animatorSetPtr, jlong propertyHolderPtr,
@@ -142,15 +144,16 @@
     holder->setPropertyDataSource(propertyData, length);
     env->ReleaseFloatArrayElements(srcData, propertyData, JNI_ABORT);
 }
-static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener) {
+static void start(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
     PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
-    // TODO: keep a ref count in finish listener
-    AnimationListener* listener = createAnimationListener(env, finishListener);
+    AnimationListener* listener = createAnimationListener(env, finishListener, id);
     set->start(listener);
 }
 
-static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener) {
-    // TODO: implement reverse
+static void reverse(JNIEnv* env, jobject, jlong animatorSetPtr, jobject finishListener, jint id) {
+    PropertyValuesAnimatorSet* set = reinterpret_cast<PropertyValuesAnimatorSet*>(animatorSetPtr);
+    AnimationListener* listener = createAnimationListener(env, finishListener, id);
+    set->reverse(listener);
 }
 
 static void end(JNIEnv*, jobject, jlong animatorSetPtr) {
@@ -172,8 +175,8 @@
     {"nCreatePathPropertyHolder", "!(JIFF)J", (void*)createPathPropertyHolder},
     {"nCreateRootAlphaPropertyHolder", "!(JFF)J", (void*)createRootAlphaPropertyHolder},
     {"nSetPropertyHolderData", "(J[FI)V", (void*)setPropertyHolderData},
-    {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V", (void*)start},
-    {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V", (void*)reverse},
+    {"nStart", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V", (void*)start},
+    {"nReverse", "(JLandroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V", (void*)reverse},
     {"nEnd", "!(J)V", (void*)end},
     {"nReset", "!(J)V", (void*)reset},
 };
@@ -186,7 +189,7 @@
 
     gVectorDrawableAnimatorClassInfo.callOnFinished = GetStaticMethodIDOrDie(
             env, gVectorDrawableAnimatorClassInfo.clazz, "callOnFinished",
-            "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;)V");
+            "(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;I)V");
     return RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedVectorDrawable",
             gMethods, NELEM(gMethods));
 }
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index bb13c35..6513304 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -31,6 +31,7 @@
 #define ENCODING_AAC_LC     10
 #define ENCODING_AAC_HE_V1  11
 #define ENCODING_AAC_HE_V2  12
+#define ENCODING_IEC61937   13
 #define ENCODING_INVALID    0
 #define ENCODING_DEFAULT    1
 
@@ -64,6 +65,8 @@
         return AUDIO_FORMAT_AAC_HE_V1;
     case ENCODING_AAC_HE_V2:
         return AUDIO_FORMAT_AAC_HE_V2;
+    case ENCODING_IEC61937:
+        return AUDIO_FORMAT_IEC61937;
     case ENCODING_DEFAULT:
         return AUDIO_FORMAT_DEFAULT;
     default:
@@ -103,6 +106,8 @@
         return ENCODING_AAC_HE_V1;
     case AUDIO_FORMAT_AAC_HE_V2:
         return ENCODING_AAC_HE_V2;
+    case AUDIO_FORMAT_IEC61937:
+        return ENCODING_IEC61937;
     case AUDIO_FORMAT_DEFAULT:
         return ENCODING_DEFAULT;
     default:
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index d25da78..d0326f1 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -693,11 +693,8 @@
         return (jint)AUDIO_JAVA_ERROR;
     }
 
-    // TODO Enable.
-#if 0
-    // get the record timestamp
     ExtendedTimestamp ts;
-    jint status = nativeToJavaStatus(lpRecorder->getExtendedTimestamp(&ts));
+    jint status = nativeToJavaStatus(lpRecorder->getTimestamp(&ts));
 
     if (status == AUDIO_JAVA_SUCCESS) {
         // set the data
@@ -712,9 +709,6 @@
         }
     }
     return status;
-#else
-    return (jint)AUDIO_JAVA_INVALID_OPERATION;
-#endif
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 8e8f6c3..80f8a64 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -128,11 +128,12 @@
     // other fields unused by JNI
 } gAudioMixingRuleFields;
 
-static jclass gAttributeMatchCriterionClass;
+static jclass gAudioMixMatchCriterionClass;
 static struct {
     jfieldID    mAttr;
+    jfieldID    mIntProp;
     jfieldID    mRule;
-} gAttributeMatchCriterionFields;
+} gAudioMixMatchCriterionFields;
 
 static jclass gAudioAttributesClass;
 static struct {
@@ -1563,22 +1564,32 @@
     }
 
     for (jint i = 0; i < numCriteria; i++) {
-        AttributeMatchCriterion nCriterion;
+        AudioMixMatchCriterion nCriterion;
 
         jobject jCriterion = env->GetObjectArrayElement(jCriteria, i);
 
-        nCriterion.mRule = env->GetIntField(jCriterion, gAttributeMatchCriterionFields.mRule);
+        nCriterion.mRule = env->GetIntField(jCriterion, gAudioMixMatchCriterionFields.mRule);
 
-        jobject jAttributes = env->GetObjectField(jCriterion, gAttributeMatchCriterionFields.mAttr);
-        if (nCriterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE ||
-                nCriterion.mRule == RULE_EXCLUDE_ATTRIBUTE_USAGE) {
-            nCriterion.mAttr.mUsage = (audio_usage_t)env->GetIntField(jAttributes,
-                                                       gAudioAttributesFields.mUsage);
-        } else {
-            nCriterion.mAttr.mSource = (audio_source_t)env->GetIntField(jAttributes,
-                                                        gAudioAttributesFields.mSource);
+        const uint32_t match_rule = nCriterion.mRule & ~RULE_EXCLUSION_MASK;
+        switch (match_rule) {
+        case RULE_MATCH_UID:
+            nCriterion.mValue.mUid = env->GetIntField(jCriterion,
+                    gAudioMixMatchCriterionFields.mIntProp);
+            break;
+        case RULE_MATCH_ATTRIBUTE_USAGE:
+        case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET: {
+            jobject jAttributes = env->GetObjectField(jCriterion, gAudioMixMatchCriterionFields.mAttr);
+            if (match_rule == RULE_MATCH_ATTRIBUTE_USAGE) {
+                nCriterion.mValue.mUsage = (audio_usage_t)env->GetIntField(jAttributes,
+                        gAudioAttributesFields.mUsage);
+            } else {
+                nCriterion.mValue.mSource = (audio_source_t)env->GetIntField(jAttributes,
+                        gAudioAttributesFields.mSource);
+            }
+            env->DeleteLocalRef(jAttributes);
+            }
+            break;
         }
-        env->DeleteLocalRef(jAttributes);
 
         nAudioMix->mCriteria.add(nCriterion);
         env->DeleteLocalRef(jCriterion);
@@ -1833,12 +1844,14 @@
     gAudioMixingRuleFields.mCriteria = GetFieldIDOrDie(env, audioMixingRuleClass, "mCriteria",
                                                        "Ljava/util/ArrayList;");
 
-    jclass attributeMatchCriterionClass =
-                FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AttributeMatchCriterion");
-    gAttributeMatchCriterionClass = MakeGlobalRefOrDie(env, attributeMatchCriterionClass);
-    gAttributeMatchCriterionFields.mAttr = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mAttr",
+    jclass audioMixMatchCriterionClass =
+                FindClassOrDie(env, "android/media/audiopolicy/AudioMixingRule$AudioMixMatchCriterion");
+    gAudioMixMatchCriterionClass = MakeGlobalRefOrDie(env,audioMixMatchCriterionClass);
+    gAudioMixMatchCriterionFields.mAttr = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mAttr",
                                                        "Landroid/media/AudioAttributes;");
-    gAttributeMatchCriterionFields.mRule = GetFieldIDOrDie(env, attributeMatchCriterionClass, "mRule",
+    gAudioMixMatchCriterionFields.mIntProp = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mIntProp",
+                                                       "I");
+    gAudioMixMatchCriterionFields.mRule = GetFieldIDOrDie(env, audioMixMatchCriterionClass, "mRule",
                                                        "I");
 
     jclass audioAttributesClass = FindClassOrDie(env, "android/media/AudioAttributes");
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 61f185e..1ab9504 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -246,7 +246,7 @@
 
     // compute the frame count
     size_t frameCount;
-    if (audio_is_linear_pcm(format)) {
+    if (audio_has_proportional_frames(format)) {
         const size_t bytesPerSample = audio_bytes_per_sample(format);
         frameCount = buffSizeInBytes / (channelCount * bytesPerSample);
     } else {
@@ -1008,7 +1008,7 @@
         return -1;
     }
     const audio_format_t format = audioFormatToNative(audioFormat);
-    if (audio_is_linear_pcm(format)) {
+    if (audio_has_proportional_frames(format)) {
         const size_t bytesPerSample = audio_bytes_per_sample(format);
         return frameCount * channelCount * bytesPerSample;
     } else {
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index 7f8f708..bfdea8f 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -161,12 +161,14 @@
   NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"),
 };
 
-void register_android_util_jar_StrictJarFile(JNIEnv* env) {
+int register_android_util_jar_StrictJarFile(JNIEnv* env) {
   jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
 
   zipEntryCtor = env->GetMethodID(JniConstants::zipEntryClass, "<init>",
       "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V");
   LOG_ALWAYS_FATAL_IF(zipEntryCtor == NULL, "Unable to find ZipEntry.<init>");
+
+  return 0;
 }
 
 }; // namespace android
diff --git a/core/jni/android_view_RenderNodeAnimator.cpp b/core/jni/android_view_RenderNodeAnimator.cpp
index 0926e9b..c9eac79 100644
--- a/core/jni/android_view_RenderNodeAnimator.cpp
+++ b/core/jni/android_view_RenderNodeAnimator.cpp
@@ -184,7 +184,7 @@
 
 static void end(JNIEnv* env, jobject clazz, jlong animatorPtr) {
     BaseRenderNodeAnimator* animator = reinterpret_cast<BaseRenderNodeAnimator*>(animatorPtr);
-    animator->end();
+    animator->cancel();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index acd0501..cd2c0d6 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "ThreadedRenderer"
 
 #include <algorithm>
+#include <atomic>
 
 #include "jni.h"
 #include <nativehelper/JNIHelp.h>
@@ -41,6 +42,7 @@
 #include <Animator.h>
 #include <AnimationContext.h>
 #include <FrameInfo.h>
+#include <FrameMetricsObserver.h>
 #include <IContextFactory.h>
 #include <JankTracker.h>
 #include <RenderNode.h>
@@ -56,10 +58,11 @@
 using namespace android::uirenderer::renderthread;
 
 struct {
-    jfieldID buffer;
+    jfieldID frameMetrics;
+    jfieldID timingDataBuffer;
     jfieldID messageQueue;
-    jmethodID notifyData;
-} gFrameStatsObserverClassInfo;
+    jmethodID callback;
+} gFrameMetricsObserverClassInfo;
 
 static JNIEnv* getenv(JavaVM* vm) {
     JNIEnv* env;
@@ -229,93 +232,137 @@
 
 class NotifyHandler : public MessageHandler {
 public:
-    NotifyHandler(JavaVM* vm) : mVm(vm) {}
-
-    void setObserver(ObserverProxy* observer) {
-        mObserver = observer;
-    }
-
-    void setBuffer(BufferPool::Buffer* buffer) {
-        mBuffer = buffer;
-    }
+    NotifyHandler(JavaVM* vm, ObserverProxy* observer) : mVm(vm), mObserver(observer) {}
 
     virtual void handleMessage(const Message& message);
 
 private:
-    JavaVM* mVm;
-
-    sp<ObserverProxy> mObserver;
-    BufferPool::Buffer* mBuffer;
+    JavaVM* const mVm;
+    ObserverProxy* const mObserver;
 };
 
-class ObserverProxy : public FrameStatsObserver {
+static jlongArray get_metrics_buffer(JNIEnv* env, jobject observer) {
+    jobject frameMetrics = env->GetObjectField(
+            observer, gFrameMetricsObserverClassInfo.frameMetrics);
+    LOG_ALWAYS_FATAL_IF(frameMetrics == nullptr, "unable to retrieve data sink object");
+    jobject buffer = env->GetObjectField(
+            frameMetrics, gFrameMetricsObserverClassInfo.timingDataBuffer);
+    LOG_ALWAYS_FATAL_IF(buffer == nullptr, "unable to retrieve data sink buffer");
+    return reinterpret_cast<jlongArray>(buffer);
+}
+
+/*
+ * Implements JNI layer for hwui frame metrics reporting.
+ */
+class ObserverProxy : public FrameMetricsObserver {
 public:
-    ObserverProxy(JavaVM *vm, jobject fso) : mVm(vm) {
+    ObserverProxy(JavaVM *vm, jobject observer) : mVm(vm) {
         JNIEnv* env = getenv(mVm);
 
-        jlongArray longArrayLocal = env->NewLongArray(kBufferSize);
-        LOG_ALWAYS_FATAL_IF(longArrayLocal == nullptr,
-                "OOM: can't allocate frame stats buffer");
-        env->SetObjectField(fso, gFrameStatsObserverClassInfo.buffer, longArrayLocal);
-
-        mFsoWeak = env->NewWeakGlobalRef(fso);
-        LOG_ALWAYS_FATAL_IF(mFsoWeak == nullptr,
+        mObserverWeak = env->NewWeakGlobalRef(observer);
+        LOG_ALWAYS_FATAL_IF(mObserverWeak == nullptr,
                 "unable to create frame stats observer reference");
 
-        jobject messageQueueLocal =
-                env->GetObjectField(fso, gFrameStatsObserverClassInfo.messageQueue);
+        jlongArray buffer = get_metrics_buffer(env, observer);
+        jsize bufferSize = env->GetArrayLength(reinterpret_cast<jarray>(buffer));
+        LOG_ALWAYS_FATAL_IF(bufferSize != kBufferSize,
+                "Mismatched Java/Native FrameMetrics data format.");
+
+        jobject messageQueueLocal = env->GetObjectField(
+                observer, gFrameMetricsObserverClassInfo.messageQueue);
         mMessageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueLocal);
         LOG_ALWAYS_FATAL_IF(mMessageQueue == nullptr, "message queue not available");
 
-        mMessageHandler = new NotifyHandler(mVm);
+        mMessageHandler = new NotifyHandler(mVm, this);
         LOG_ALWAYS_FATAL_IF(mMessageHandler == nullptr,
                 "OOM: unable to allocate NotifyHandler");
     }
 
     ~ObserverProxy() {
         JNIEnv* env = getenv(mVm);
-        env->DeleteWeakGlobalRef(mFsoWeak);
+        env->DeleteWeakGlobalRef(mObserverWeak);
     }
 
-    jweak getJavaObjectRef() {
-        return mFsoWeak;
+    jweak getObserverReference() {
+        return mObserverWeak;
     }
 
-    virtual void notify(BufferPool::Buffer* buffer) {
-        buffer->incRef();
-        mMessageHandler->setBuffer(buffer);
-        mMessageHandler->setObserver(this);
-        mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
+    bool getNextBuffer(JNIEnv* env, jlongArray sink, int* dropCount) {
+        FrameMetricsNotification& elem = mRingBuffer[mNextInQueue];
+
+        if (elem.hasData.load()) {
+            env->SetLongArrayRegion(sink, 0, kBufferSize, elem.buffer);
+            *dropCount = elem.dropCount;
+            mNextInQueue = (mNextInQueue + 1) % kRingSize;
+            elem.hasData = false;
+            return true;
+        }
+
+        return false;
+    }
+
+    virtual void notify(const int64_t* stats) {
+        FrameMetricsNotification& elem = mRingBuffer[mNextFree];
+
+        if (!elem.hasData.load()) {
+            memcpy(elem.buffer, stats, kBufferSize * sizeof(stats[0]));
+
+            elem.dropCount = mDroppedReports;
+            mDroppedReports = 0;
+
+            incStrong(nullptr);
+            mNextFree = (mNextFree + 1) % kRingSize;
+            elem.hasData = true;
+
+            mMessageQueue->getLooper()->sendMessage(mMessageHandler, mMessage);
+        } else {
+            mDroppedReports++;
+        }
     }
 
 private:
     static const int kBufferSize = static_cast<int>(FrameInfoIndex::NumIndexes);
+    static constexpr int kRingSize = 3;
 
-    JavaVM* mVm;
-    jweak mFsoWeak;
+    class FrameMetricsNotification {
+    public:
+        FrameMetricsNotification() : hasData(false) {}
+
+        std::atomic_bool hasData;
+        int64_t buffer[kBufferSize];
+        int dropCount = 0;
+    };
+
+    JavaVM* const mVm;
+    jweak mObserverWeak;
+    jobject mJavaBufferGlobal;
 
     sp<MessageQueue> mMessageQueue;
     sp<NotifyHandler> mMessageHandler;
     Message mMessage;
+
+    int mNextFree = 0;
+    int mNextInQueue = 0;
+    FrameMetricsNotification mRingBuffer[kRingSize];
+
+    int mDroppedReports = 0;
 };
 
 void NotifyHandler::handleMessage(const Message& message) {
     JNIEnv* env = getenv(mVm);
 
-    jobject target = env->NewLocalRef(mObserver->getJavaObjectRef());
+    jobject target = env->NewLocalRef(mObserver->getObserverReference());
 
     if (target != nullptr) {
-        jobject javaBuffer = env->GetObjectField(target, gFrameStatsObserverClassInfo.buffer);
-        if (javaBuffer != nullptr) {
-            env->SetLongArrayRegion(reinterpret_cast<jlongArray>(javaBuffer),
-                    0, mBuffer->getSize(), mBuffer->getBuffer());
-            env->CallVoidMethod(target, gFrameStatsObserverClassInfo.notifyData);
-            env->DeleteLocalRef(target);
+        jlongArray javaBuffer = get_metrics_buffer(env, target);
+        int dropCount = 0;
+        while (mObserver->getNextBuffer(env, javaBuffer, &dropCount)) {
+            env->CallVoidMethod(target, gFrameMetricsObserverClassInfo.callback, dropCount);
         }
+        env->DeleteLocalRef(target);
     }
 
-    mBuffer->release();
-    mObserver.clear();
+    mObserver->decStrong(nullptr);
 }
 
 static void android_view_ThreadedRenderer_setAtlas(JNIEnv* env, jobject clazz,
@@ -579,10 +626,10 @@
 }
 
 // ----------------------------------------------------------------------------
-// FrameStatsObserver
+// FrameMetricsObserver
 // ----------------------------------------------------------------------------
 
-static jlong android_view_ThreadedRenderer_addFrameStatsObserver(JNIEnv* env,
+static jlong android_view_ThreadedRenderer_addFrameMetricsObserver(JNIEnv* env,
         jclass clazz, jlong proxyPtr, jobject fso) {
     JavaVM* vm = nullptr;
     if (env->GetJavaVM(&vm) != JNI_OK) {
@@ -593,25 +640,18 @@
     renderthread::RenderProxy* renderProxy =
             reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
 
-    FrameStatsObserver* observer = new ObserverProxy(vm, fso);
-    renderProxy->addFrameStatsObserver(observer);
+    FrameMetricsObserver* observer = new ObserverProxy(vm, fso);
+    renderProxy->addFrameMetricsObserver(observer);
     return reinterpret_cast<jlong>(observer);
 }
 
-static void android_view_ThreadedRenderer_removeFrameStatsObserver(JNIEnv* env, jclass clazz,
+static void android_view_ThreadedRenderer_removeFrameMetricsObserver(JNIEnv* env, jclass clazz,
         jlong proxyPtr, jlong observerPtr) {
-    FrameStatsObserver* observer = reinterpret_cast<FrameStatsObserver*>(observerPtr);
+    FrameMetricsObserver* observer = reinterpret_cast<FrameMetricsObserver*>(observerPtr);
     renderthread::RenderProxy* renderProxy =
             reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
 
-    renderProxy->removeFrameStatsObserver(observer);
-}
-
-static jint android_view_ThreadedRenderer_getDroppedFrameReportCount(JNIEnv* env, jclass clazz,
-        jlong proxyPtr) {
-    renderthread::RenderProxy* renderProxy =
-            reinterpret_cast<renderthread::RenderProxy*>(proxyPtr);
-    return renderProxy->getDroppedFrameReportCount();
+    renderProxy->removeFrameMetricsObserver(observer);
 }
 
 // ----------------------------------------------------------------------------
@@ -684,25 +724,26 @@
     { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
     { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
     { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
-    { "nAddFrameStatsObserver",
-            "(JLandroid/view/FrameStatsObserver;)J",
-            (void*)android_view_ThreadedRenderer_addFrameStatsObserver },
-    { "nRemoveFrameStatsObserver",
+    { "nAddFrameMetricsObserver",
+            "(JLandroid/view/FrameMetricsObserver;)J",
+            (void*)android_view_ThreadedRenderer_addFrameMetricsObserver },
+    { "nRemoveFrameMetricsObserver",
             "(JJ)V",
-            (void*)android_view_ThreadedRenderer_removeFrameStatsObserver },
-    { "nGetDroppedFrameReportCount",
-            "(J)J",
-            (void*)android_view_ThreadedRenderer_getDroppedFrameReportCount },
+            (void*)android_view_ThreadedRenderer_removeFrameMetricsObserver },
 };
 
 int register_android_view_ThreadedRenderer(JNIEnv* env) {
-    jclass clazz = FindClassOrDie(env, "android/view/FrameStatsObserver");
-    gFrameStatsObserverClassInfo.messageQueue  =
-            GetFieldIDOrDie(env, clazz, "mMessageQueue", "Landroid/os/MessageQueue;");
-    gFrameStatsObserverClassInfo.buffer =
-            GetFieldIDOrDie(env, clazz, "mBuffer", "[J");
-    gFrameStatsObserverClassInfo.notifyData =
-            GetMethodIDOrDie(env, clazz, "notifyDataAvailable", "()V");
+    jclass observerClass = FindClassOrDie(env, "android/view/FrameMetricsObserver");
+    gFrameMetricsObserverClassInfo.frameMetrics = GetFieldIDOrDie(
+            env, observerClass, "mFrameMetrics", "Landroid/view/FrameMetrics;");
+    gFrameMetricsObserverClassInfo.messageQueue = GetFieldIDOrDie(
+            env, observerClass, "mMessageQueue", "Landroid/os/MessageQueue;");
+    gFrameMetricsObserverClassInfo.callback = GetMethodIDOrDie(
+            env, observerClass, "notifyDataAvailable", "(I)V");
+
+    jclass metricsClass = FindClassOrDie(env, "android/view/FrameMetrics");
+    gFrameMetricsObserverClassInfo.timingDataBuffer = GetFieldIDOrDie(
+            env, metricsClass, "mTimingData", "[J");
 
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4cddb6c..7699da7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -397,6 +397,7 @@
     <protected-broadcast android:name="com.android.settings.location.MODE_CHANGING" />
 
     <protected-broadcast android:name="ScheduleConditionProvider.EVALUATE" />
+    <protected-broadcast android:name="EventConditionProvider.EVALUATE" />
     <protected-broadcast android:name="wifi_scan_available" />
 
     <protected-broadcast android:name="action.cne.started" />
@@ -425,6 +426,23 @@
 
     <protected-broadcast android:name="android.intent.action.DYNAMIC_SENSOR_CHANGED" />
 
+    <protected-broadcast android:name="android.intent.action.ACTION_RADIO_OFF" />
+    <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNLOCKED" />
+
+    <protected-broadcast android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" />
+    <protected-broadcast android:name="com.android.sync.SYNC_CONN_STATUS_CHANGED" />
+
+    <protected-broadcast android:name="com.android.phone.SIP_INCOMING_CALL" />
+    <protected-broadcast android:name="com.android.phone.SIP_ADD_PHONE" />
+    <protected-broadcast android:name="com.android.phone.SIP_REMOVE_PHONE" />
+    <protected-broadcast android:name="com.android.phone.SIP_CALL_OPTION_CHANGED" />
+
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_CONNECTED" />
+    <protected-broadcast android:name="android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED" />
+
+    <protected-broadcast android:name="android.bluetooth.input.profile.action.HANDSHAKE" />
+    <protected-broadcast android:name="android.bluetooth.input.profile.action.REPORT" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -968,8 +986,7 @@
 
     <!-- @SystemApi Allows an application to receive emergency cell broadcast messages,
          to record or display them to the user.
-         <p>Not for use by third-party applications.
-         @hide Pending API council approval -->
+         <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"
         android:protectionLevel="signature|privileged" />
 
@@ -2884,6 +2901,18 @@
     <permission android:name="android.permission.DISPATCH_PROVISIONING_MESSAGE"
                 android:protectionLevel="signature|privileged" />
 
+    <!-- Allows the holder to read blocked numbers. See
+         {@link android.provider.BlockedNumberContract}.
+         @hide -->
+    <permission android:name="android.permission.READ_BLOCKED_NUMBERS"
+                android:protectionLevel="signature" />
+
+    <!-- Allows the holder to write blocked numbers. See
+         {@link android.provider.BlockedNumberContract}.
+         @hide -->
+    <permission android:name="android.permission.WRITE_BLOCKED_NUMBERS"
+                android:protectionLevel="signature" />
+
     <application android:process="system"
                  android:persistent="true"
                  android:hasCode="false"
diff --git a/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml b/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml
index 2dd0540..62af834 100644
--- a/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml
+++ b/core/res/res/drawable/ic_arrow_drop_right_black_24dp.xml
@@ -15,10 +15,10 @@
 -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:height="25.0dp"
-    android:viewportHeight="25.0"
+    android:height="24.0dp"
+    android:viewportHeight="24.0"
     android:viewportWidth="24.0"
-    android:width="25.0dp"
+    android:width="24.0dp"
     android:tint="?attr/colorControlNormal"
     android:autoMirrored="true">
 
@@ -26,9 +26,8 @@
         android:name="arrow"
         android:rotation="90.0"
         android:pivotX="12.0"
-        android:pivotY="13.0"
-        android:translateY="1.0">
+        android:pivotY="12.0">
         <path android:fillColor="#000000" android:pathData="M7,14 L12,9 L17,14 L7,14 Z" />
         <path android:pathData="M0,0 L24,0 L24,24 L0,24 L0,0 Z" />
     </group>
-</vector>
\ No newline at end of file
+</vector>
diff --git a/core/res/res/layout/floating_popup_container.xml b/core/res/res/layout/floating_popup_container.xml
index dd161e3..ca03737 100644
--- a/core/res/res/layout/floating_popup_container.xml
+++ b/core/res/res/layout/floating_popup_container.xml
@@ -19,8 +19,8 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:padding="0dp"
-    android:layout_margin="20dp"
-    android:elevation="2dp"
+    android:layout_margin="@android:dimen/text_edit_floating_toolbar_margin"
+    android:elevation="@android:dimen/text_edit_floating_toolbar_elevation"
     android:focusable="true"
     android:focusableInTouchMode="true"
     android:background="?attr/floatingToolbarPopupBackgroundDrawable"/>
diff --git a/core/res/res/layout/language_picker_section_header.xml b/core/res/res/layout/language_picker_section_header.xml
index c4d3069..b12ec8c 100644
--- a/core/res/res/layout/language_picker_section_header.xml
+++ b/core/res/res/layout/language_picker_section_header.xml
@@ -19,7 +19,8 @@
           style="?android:attr/preferenceCategoryStyle"
           android:layout_width="match_parent"
           android:layout_height="36dp"
-          android:paddingStart="12dp"
-          android:paddingEnd="12dp"
+          android:gravity="center_vertical"
+          android:paddingStart="18dp"
+          android:paddingEnd="18dp"
           android:textColor="?android:attr/colorAccent"
           tools:text="@string/language_picker_section_all"/>
diff --git a/core/res/res/layout/notification_material_action.xml b/core/res/res/layout/notification_material_action.xml
index 398f52d..548ee05 100644
--- a/core/res/res/layout/notification_material_action.xml
+++ b/core/res/res/layout/notification_material_action.xml
@@ -21,6 +21,7 @@
     android:layout_width="wrap_content"
     android:layout_height="48dp"
     android:layout_gravity="center"
+    android:gravity="start|center_vertical"
     android:layout_marginStart="4dp"
     android:textColor="@color/notification_default_color"
     android:singleLine="true"
diff --git a/core/res/res/layout/notification_material_action_tombstone.xml b/core/res/res/layout/notification_material_action_tombstone.xml
index 976448b..1f59ea0 100644
--- a/core/res/res/layout/notification_material_action_tombstone.xml
+++ b/core/res/res/layout/notification_material_action_tombstone.xml
@@ -18,16 +18,15 @@
 <Button xmlns:android="http://schemas.android.com/apk/res/android"
     style="@android:style/Widget.Material.Light.Button.Borderless.Small"
     android:id="@+id/action0"
-    android:layout_width="0dp"
+    android:layout_width="wrap_content"
     android:layout_height="48dp"
-    android:layout_weight="1"
+    android:layout_marginStart="4dp"
+    android:layout_gravity="center"
     android:gravity="start|center_vertical"
-    android:drawablePadding="8dp"
-    android:paddingStart="8dp"
     android:textColor="#555555"
-    android:textSize="@dimen/notification_text_size"
     android:singleLine="true"
     android:ellipsize="end"
     android:alpha="0.5"
     android:enabled="false"
+    android:background="@drawable/notification_material_action_background"
     />
diff --git a/core/res/res/layout/text_edit_suggestion_container.xml b/core/res/res/layout/text_edit_suggestion_container.xml
index 17e93d0..b2589da 100644
--- a/core/res/res/layout/text_edit_suggestion_container.xml
+++ b/core/res/res/layout/text_edit_suggestion_container.xml
@@ -22,8 +22,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="vertical"
-        android:elevation="2dp"
-        android:layout_margin="20dp"
+        android:elevation="@android:dimen/text_edit_floating_toolbar_elevation"
+        android:layout_margin="@android:dimen/text_edit_floating_toolbar_margin"
         android:background="@drawable/text_edit_suggestions_window"
         android:dropDownSelector="@drawable/list_selector_background"
         android:divider="@null">
diff --git a/core/res/res/layout/text_edit_suggestion_container_material.xml b/core/res/res/layout/text_edit_suggestion_container_material.xml
index 7826803..20a80489 100644
--- a/core/res/res/layout/text_edit_suggestion_container_material.xml
+++ b/core/res/res/layout/text_edit_suggestion_container_material.xml
@@ -24,8 +24,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:background="?android:attr/floatingToolbarPopupBackgroundDrawable"
-        android:elevation="2dp"
-        android:layout_margin="20dp"
+        android:elevation="@android:dimen/text_edit_floating_toolbar_elevation"
+        android:layout_margin="@android:dimen/text_edit_floating_toolbar_margin"
         android:orientation="vertical"
         android:divider="?android:attr/listDivider"
         android:showDividers="middle">
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index c8ab295..6b158dc 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Raak vir meer opsies."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Deel foutverslag met administrateur?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jou IT-administrateur het \'n foutverslag versoek om met foutsporing te help"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AANVAAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"WEIER"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Neem tans foutverslag …"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Raak om te kanselleer"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Verander sleutelbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Kies sleutelborde"</string>
     <string name="show_ime" msgid="2506087537466597099">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Deur %1$s-administrateur gedeaktiveer. Kontak hulle om meer uit te vind."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Jy het nuwe boodskappe"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Maak SMS-program oop om te bekyk"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Party funksies dalk nie beskikbaar nie"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Raak om voort te gaan"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Gebruikerprofiel is gesluit"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Sommige funksies kan beperk wees"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tik om te ontsluit"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Gebruikerdata is gesluit"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Werkprofiel is gesluit"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tik om werkprofiel te ontsluit"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Gekoppel aan <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tik om lêers te bekyk"</string>
     <string name="pin_target" msgid="3052256031352291362">"Speld vas"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ec533aa..5332c62 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ለተጨማሪ አማራጮች ነካ ያድርጉ።"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ማረሚያ ላለማንቃት ዳስስ።"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"የሳንካ ሪፖርት ለአስተዳዳሪ ይጋራ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"የእርስዎ የአይቲ አስተዳዳሪ መላ መፈለግ ላይ እንዲያግዝ የሳንካ ሪፖርት ጠይቀዋል"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ተቀበል"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ውድቅ አድርግ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ለመሰረዝ ይንኩ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ቁልፍ ሰሌዳ ይቀይሩ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ቁልፍ ሰሌዳዎችን ምረጥ"</string>
     <string name="show_ime" msgid="2506087537466597099">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"በ%1$s አስተዳዳሪ ተሰናክሏል። የበለጠ ለመረዳት ያነጋግሯቸው።"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"አዲስ መልእክቶች አለዎት"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"ለመመልከት የኤስኤምኤስ መተግበሪያ ይክፈቱ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"አንዳንድ ተግባሮች ላይገኙ ይችላሉ"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ለመቀጠል ይንኩ"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"የተጠቃሚ መገለጫ ተቆልፏል"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"አንዳንድ ተግባሮች የተገደቡ ሊሆኑ ይችላሉ"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ለመክፈት መታ ያድርጉ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"የተጠቃሚ ውሂብ ተቆልፏል"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"የስራ መገለጫ ተቆልፏል"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"የስራ መገለጫውን እገዳ ለማንሳት መታ ያድርጉ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"ከ<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ጋር ተገናኝቷል"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ፋይሎችን ለመመልከት መታ ያድርጉ"</string>
     <string name="pin_target" msgid="3052256031352291362">"ፒን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index e927d54..e592fb9 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1085,12 +1085,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"المس للحصول على مزيد من الخيارات."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏المس لتعطيل تصحيح أخطاء USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"هل تريد مشاركة تقرير الأخطاء مع المشرف؟"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"طلب مشرف تكنولوجيا المعلومات الحصول على تقرير بالأخطاء للمساعدة في تحري الخلل وإصلاحه"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"قبول"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"رفض"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"جارٍ الحصول على تقرير بالأخطاء…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"المس للإلغاء"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغيير لوحة المفاتيح"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"اختيار لوحات المفاتيح"</string>
     <string name="show_ime" msgid="2506087537466597099">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
@@ -1631,9 +1637,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"‏تم التعطيل بواسطة مشرف %1$s. يمكنك الاتصال به لمعرفة المزيد."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"لديك رسائل جديدة"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"‏فتح تطبيق الرسائل القصيرة SMS للعرض"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"قد لا تكون بعض الوظائف متاحة"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"المس للمتابعة"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"تم قفل الملف الشخصي للمستخدم"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ربما تكون بعض الوظائف مُقيّدة."</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"انقر لإلغاء القفل."</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"تم قفل بيانات المستخدم."</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"تم قفل الملف الشخصي للعمل."</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"انقر لإلغاء قفل الملف الشخصي للعمل"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"تم الاتصال بـ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"انقر لعرض الملفات"</string>
     <string name="pin_target" msgid="3052256031352291362">"تثبيت"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 211346f..7313063 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1031,7 +1031,7 @@
     <string name="sim_added_title" msgid="3719670512889674693">"SİM kart əlavə edildi"</string>
     <string name="sim_added_message" msgid="7797975656153714319">"Mobil şəbəkəyə giriş üçün cihazınızı sıfırlayın."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Yenidən başlat"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"Yeni SIM kartınızın düzgün işləməsi üçün, operatorunuzdan tətbiq yükləməli və açmalısınız."</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"Yeni SIM kartınızın düzgün işləməsi üçün operatorunuzdan tətbiq yükləməli və açmalısınız."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"TƏTBİQİ ƏLDƏ EDİN"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"İNDİ YOX"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Yeni SIM kart taxılıb"</string>
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Əlavə seçimlər üçün toxunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Baq hesabatı admin ilə paylaşılsın?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT admininiz nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"QƏBUL EDİN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RƏDD ET"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Baq xəbər verilir..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ləğv etmək üçün toxunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturaları seçin"</string>
     <string name="show_ime" msgid="2506087537466597099">"Fiziki klaviatura aktiv olduğu halda ekranda saxlayın"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s administratoru tərəfindən deaktiv edildi. Ətraflı məlumat üçün onlarla əlaqə saxlayın."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Yeni mesajlarınız var"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Baxmaq üçün SMS tətbiqini açın"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Bəzi funksiyalar əlçatan olmaya bilər"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Davam etmək üçün toxunun"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"İstifadəçi profili kilidlidir"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Bir neçə funksionallıq məhdudlaşdırıla bilər"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Kilidi açmaq üçün tıklayın"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"İstifadəçi datası kilidlidir"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"İş profili kilidlidir"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmaq üçün tıklayın"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> məhsuluna bağlandı"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Faylları görmək üçün basın"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pin kod"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 3edd5b7..3206faa 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1061,12 +1061,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za još opcija."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite li da delite izveštaj o grešci sa administratorom?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIHVATI"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODBIJ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Izveštaj o grešci se generiše…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izaberite tastature"</string>
     <string name="show_ime" msgid="2506087537466597099">"Zadrži ga na ekranu dok je fizička tastatura aktivna"</string>
@@ -1574,9 +1580,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Onemogućio je administrator kompanije %1$s. Kontaktirajte ga da biste saznali više."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite aplikaciju za SMS da biste pregledali"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Neke funkcije nisu dostupne"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Dodirnite da biste nastavili"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil korisnika je zaključan"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Neke funkcije su možda ograničene"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Dodirnite da biste otključali"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Podaci korisnika su zaključani"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil za Work je zaključan"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirom otklj. profil za Work"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Povezano je sa proizvodom <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite za pregled datoteka"</string>
     <string name="pin_target" msgid="3052256031352291362">"Zakači"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index cefa04d..a5255a6 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Докоснете за още опции."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете за деактивиране"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Да се сподели ли сигналът за програмна грешка с администратора?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Системният ви администратор заяви сигнал за програмна грешка с цел отстраняване на неизправностите"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИЕМАМ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОТХВЪРЛЯМ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Сигналът за програмна грешка се извлича…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Докоснете, за да анулирате"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промяна на клавиатурата"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избиране на клавиатури"</string>
     <string name="show_ime" msgid="2506087537466597099">"Показване на екрана, докато физическата клавиатура е активна"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Деактивирано от администратора на %1$s. Свържете се с него, за да научите повече."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Имате нови съобщения"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Преглед в приложението за SMS"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Някои функции може да не са налице"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Докоснете, за да продължите"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Потр. профил е заключен"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Някои функции може да са огранич."</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Докоснете, за да отключите"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Потр. данни са заключени"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Служ. потр. профил е заключен"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Докоснете за откл. на служ. потр. профил"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Установена е връзка с <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Докоснете, за да прегледате файловете"</string>
     <string name="pin_target" msgid="3052256031352291362">"Фиксиране"</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 39fec29..eacfd3b 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"আরো বিকল্পের জন্য স্পর্শ করুন৷"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ডিবাগিং অক্ষম করতে স্পর্শ করুন৷"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"প্রশাসকের সাথে ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"আপনার IT প্রশাসক সমস্যা নিবারণে সহায়তা করতে একটি ত্রুটির প্রতিবেদন চেয়েছেন"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"স্বীকার করুন"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"অস্বীকার করুন"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"বাতিল করতে স্পর্শ করুন"</string>
     <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"কীবোর্ড চয়ন করুন"</string>
     <string name="show_ime" msgid="2506087537466597099">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string>
@@ -1430,7 +1436,7 @@
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"বাতিল করা হয়েছে"</string>
     <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"সামগ্রী লেখায় ত্রুটি হয়েছে"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"অজানা"</string>
-    <string name="reason_service_unavailable" msgid="7824008732243903268">"মুদ্রণ পরিষেবা সক্ষম করা নেই"</string>
+    <string name="reason_service_unavailable" msgid="7824008732243903268">"প্রিন্ট পরিষেবা সক্ষম করা নেই"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> পরিষেবা ইনস্টল হয়েছে"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"সক্ষম করতে আলতো চাপুন"</string>
     <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"প্রশাসক পিন লিখুন"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s প্রশাসক অক্ষম করেছেন। আরো জানতে তাদের সাথে যোগাযোগ করুন।"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"আপনার নতুন বার্তা আছে"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"দেখার জন্য SMS অ্যাপ্লিকেশান খুলুন"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"কিছু ক্রিয়াকলাপ উপলব্ধ নাও হতে পারে"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"অবিরত রাখতে স্পর্শ করুন"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ব্যবহারকারীর প্রোফাইল লক করা আছে"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"কিছু ক্রিয়াকলাপ সীমিত হতে পারে"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"আনলক করতে আলতো চাপ দিন"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ব্যবহারকারির ডেটা লক করা হয়েছে"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"কর্মস্থলের প্রোফাইল লক করা আছে"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"কর্মস্থলের প্রোফাইল আনলক করতে আলতো চাপ দিন"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> এর সাথে সংযুক্ত হয়েছে"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ফাইলগুলি দেখতে আলতো চাপ দিন"</string>
     <string name="pin_target" msgid="3052256031352291362">"পিন করুন"</string>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index ed31fce..84e2826 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -20,1681 +20,903 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for byteShort (8340973892742019101) -->
-    <skip />
-    <!-- no translation found for kilobyteShort (5973789783504771878) -->
-    <skip />
-    <!-- no translation found for megabyteShort (6355851576770428922) -->
-    <skip />
-    <!-- no translation found for gigabyteShort (3259882455212193214) -->
-    <skip />
-    <!-- no translation found for terabyteShort (231613018159186962) -->
-    <skip />
-    <!-- no translation found for petabyteShort (5637816680144990219) -->
-    <skip />
-    <!-- no translation found for fileSizeSuffix (8897567456150907538) -->
-    <skip />
-    <!-- no translation found for durationDays (6652371460511178259) -->
-    <skip />
-    <!-- no translation found for durationDayHours (2713107458736744435) -->
-    <skip />
-    <!-- no translation found for durationDayHour (7293789639090958917) -->
-    <skip />
-    <!-- no translation found for durationHours (4266858287167358988) -->
-    <skip />
-    <!-- no translation found for durationHourMinutes (9029176248692041549) -->
-    <skip />
-    <!-- no translation found for durationHourMinute (2741677355177402539) -->
-    <skip />
-    <!-- no translation found for durationMinutes (3134226679883579347) -->
-    <skip />
-    <!-- no translation found for durationMinute (7155301744174623818) -->
-    <skip />
-    <!-- no translation found for durationMinuteSeconds (1424656185379003751) -->
-    <skip />
-    <!-- no translation found for durationMinuteSecond (3989228718067466680) -->
-    <skip />
-    <!-- no translation found for durationSeconds (8050088505238241405) -->
-    <skip />
-    <!-- no translation found for durationSecond (985669622276420331) -->
-    <skip />
-    <!-- no translation found for untitled (4638956954852782576) -->
-    <skip />
-    <!-- no translation found for emptyPhoneNumber (7694063042079676517) -->
-    <skip />
-    <!-- no translation found for unknownName (6867811765370350269) -->
-    <skip />
-    <!-- no translation found for defaultVoiceMailAlphaTag (2660020990097733077) -->
-    <skip />
-    <!-- no translation found for defaultMsisdnAlphaTag (2850889754919584674) -->
-    <skip />
-    <!-- no translation found for mmiError (5154499457739052907) -->
-    <skip />
-    <!-- no translation found for mmiFdnError (5224398216385316471) -->
-    <skip />
-    <!-- no translation found for serviceEnabled (8147278346414714315) -->
-    <skip />
-    <!-- no translation found for serviceEnabledFor (6856228140453471041) -->
-    <skip />
-    <!-- no translation found for serviceDisabled (1937553226592516411) -->
-    <skip />
-    <!-- no translation found for serviceRegistered (6275019082598102493) -->
-    <skip />
-    <!-- no translation found for serviceErased (1288584695297200972) -->
-    <skip />
-    <!-- no translation found for passwordIncorrect (7612208839450128715) -->
-    <skip />
-    <!-- no translation found for mmiComplete (8232527495411698359) -->
-    <skip />
-    <!-- no translation found for badPin (9015277645546710014) -->
-    <skip />
-    <!-- no translation found for badPuk (5487257647081132201) -->
-    <skip />
-    <!-- no translation found for mismatchPin (609379054496863419) -->
-    <skip />
-    <!-- no translation found for invalidPin (3850018445187475377) -->
-    <skip />
-    <!-- no translation found for invalidPuk (8761456210898036513) -->
-    <skip />
-    <!-- no translation found for needPuk (919668385956251611) -->
-    <skip />
-    <!-- no translation found for needPuk2 (4526033371987193070) -->
-    <skip />
-    <!-- no translation found for enablePin (209412020907207950) -->
-    <skip />
-    <!-- no translation found for pinpuk_attempts (1251012001539225582) -->
-    <!-- no translation found for imei (2625429890869005782) -->
-    <skip />
-    <!-- no translation found for meid (4841221237681254195) -->
-    <skip />
-    <!-- no translation found for ClipMmi (6952821216480289285) -->
-    <skip />
-    <!-- no translation found for ClirMmi (7784673673446833091) -->
-    <skip />
-    <!-- no translation found for ColpMmi (3065121483740183974) -->
-    <skip />
-    <!-- no translation found for ColrMmi (4996540314421889589) -->
-    <skip />
-    <!-- no translation found for CfMmi (5123218989141573515) -->
-    <skip />
-    <!-- no translation found for CwMmi (9129678056795016867) -->
-    <skip />
-    <!-- no translation found for BaMmi (455193067926770581) -->
-    <skip />
-    <!-- no translation found for PwdMmi (7043715687905254199) -->
-    <skip />
-    <!-- no translation found for PinMmi (3113117780361190304) -->
-    <skip />
-    <!-- no translation found for CnipMmi (3110534680557857162) -->
-    <skip />
-    <!-- no translation found for CnirMmi (3062102121430548731) -->
-    <skip />
-    <!-- no translation found for ThreeWCMmi (9051047170321190368) -->
-    <skip />
-    <!-- no translation found for RuacMmi (7827887459138308886) -->
-    <skip />
-    <!-- no translation found for CndMmi (3116446237081575808) -->
-    <skip />
-    <!-- no translation found for DndMmi (1265478932418334331) -->
-    <skip />
-    <!-- no translation found for CLIRDefaultOnNextCallOn (429415409145781923) -->
-    <skip />
-    <!-- no translation found for CLIRDefaultOnNextCallOff (3092918006077864624) -->
-    <skip />
-    <!-- no translation found for CLIRDefaultOffNextCallOn (6179425182856418465) -->
-    <skip />
-    <!-- no translation found for CLIRDefaultOffNextCallOff (2567998633124408552) -->
-    <skip />
-    <!-- no translation found for serviceNotProvisioned (8614830180508686666) -->
-    <skip />
-    <!-- no translation found for CLIRPermanent (3377371145926835671) -->
-    <skip />
-    <!-- no translation found for RestrictedChangedTitle (5592189398956187498) -->
-    <skip />
-    <!-- no translation found for RestrictedOnData (8653794784690065540) -->
-    <skip />
-    <!-- no translation found for RestrictedOnEmergency (6581163779072833665) -->
-    <skip />
-    <!-- no translation found for RestrictedOnNormal (4953867011389750673) -->
-    <skip />
-    <!-- no translation found for RestrictedOnAllVoice (3396963652108151260) -->
-    <skip />
-    <!-- no translation found for RestrictedOnSms (8314352327461638897) -->
-    <skip />
-    <!-- no translation found for RestrictedOnVoiceData (996636487106171320) -->
-    <skip />
-    <!-- no translation found for RestrictedOnVoiceSms (1888588152792023873) -->
-    <skip />
-    <!-- no translation found for RestrictedOnAll (5643028264466092821) -->
-    <skip />
-    <!-- no translation found for peerTtyModeFull (6165351790010341421) -->
-    <skip />
-    <!-- no translation found for peerTtyModeHco (5728602160669216784) -->
-    <skip />
-    <!-- no translation found for peerTtyModeVco (1742404978686538049) -->
-    <skip />
-    <!-- no translation found for peerTtyModeOff (3280819717850602205) -->
-    <skip />
-    <!-- no translation found for serviceClassVoice (1258393812335258019) -->
-    <skip />
-    <!-- no translation found for serviceClassData (872456782077937893) -->
-    <skip />
-    <!-- no translation found for serviceClassFAX (5566624998840486475) -->
-    <skip />
-    <!-- no translation found for serviceClassSMS (2015460373701527489) -->
-    <skip />
-    <!-- no translation found for serviceClassDataAsync (4523454783498551468) -->
-    <skip />
-    <!-- no translation found for serviceClassDataSync (7530000519646054776) -->
-    <skip />
-    <!-- no translation found for serviceClassPacket (6991006557993423453) -->
-    <skip />
-    <!-- no translation found for serviceClassPAD (3235259085648271037) -->
-    <skip />
-    <!-- no translation found for roamingText0 (7170335472198694945) -->
-    <skip />
-    <!-- no translation found for roamingText1 (5314861519752538922) -->
-    <skip />
-    <!-- no translation found for roamingText2 (8969929049081268115) -->
-    <skip />
-    <!-- no translation found for roamingText3 (5148255027043943317) -->
-    <skip />
-    <!-- no translation found for roamingText4 (8808456682550796530) -->
-    <skip />
-    <!-- no translation found for roamingText5 (7604063252850354350) -->
-    <skip />
-    <!-- no translation found for roamingText6 (2059440825782871513) -->
-    <skip />
-    <!-- no translation found for roamingText7 (7112078724097233605) -->
-    <skip />
-    <!-- no translation found for roamingText8 (5989569778604089291) -->
-    <skip />
-    <!-- no translation found for roamingText9 (7969296811355152491) -->
-    <skip />
-    <!-- no translation found for roamingText10 (3992906999815316417) -->
-    <skip />
-    <!-- no translation found for roamingText11 (4154476854426920970) -->
-    <skip />
-    <!-- no translation found for roamingText12 (1189071119992726320) -->
-    <skip />
-    <!-- no translation found for roamingTextSearching (8360141885972279963) -->
-    <skip />
-    <!-- no translation found for wfcRegErrorTitle (2301376280632110664) -->
-    <skip />
+    <string name="byteShort" msgid="8340973892742019101">"B"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> dana"</string>
+    <string name="durationDayHours" msgid="2713107458736744435">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sati"</string>
+    <string name="durationDayHour" msgid="7293789639090958917">"<xliff:g id="DAYS">%1$d</xliff:g> dan <xliff:g id="HOURS">%2$d</xliff:g> sat"</string>
+    <string name="durationHours" msgid="4266858287167358988">"<xliff:g id="HOURS">%1$d</xliff:g> sati"</string>
+    <string name="durationHourMinutes" msgid="9029176248692041549">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationHourMinute" msgid="2741677355177402539">"<xliff:g id="HOURS">%1$d</xliff:g> sat <xliff:g id="MINUTES">%2$d</xliff:g> min"</string>
+    <string name="durationMinutes" msgid="3134226679883579347">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
+    <string name="durationMinute" msgid="7155301744174623818">"<xliff:g id="MINUTES">%1$d</xliff:g> min"</string>
+    <string name="durationMinuteSeconds" msgid="1424656185379003751">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+    <string name="durationMinuteSecond" msgid="3989228718067466680">"<xliff:g id="MINUTES">%1$d</xliff:g> min <xliff:g id="SECONDS">%2$d</xliff:g> sek"</string>
+    <string name="durationSeconds" msgid="8050088505238241405">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
+    <string name="durationSecond" msgid="985669622276420331">"<xliff:g id="SECONDS">%1$d</xliff:g> sek"</string>
+    <string name="untitled" msgid="4638956954852782576">"&lt;Bez naslova&gt;"</string>
+    <string name="emptyPhoneNumber" msgid="7694063042079676517">"(Nema broja telefona)"</string>
+    <string name="unknownName" msgid="6867811765370350269">"Nepoznato"</string>
+    <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Govorna pošta"</string>
+    <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string>
+    <string name="mmiError" msgid="5154499457739052907">"Problem sa povezivanjem ili nevažeći MMI kôd."</string>
+    <string name="mmiFdnError" msgid="5224398216385316471">"Operacija je ograničena samo na brojeve fiksnog biranja."</string>
+    <string name="serviceEnabled" msgid="8147278346414714315">"Usluga je omogućena."</string>
+    <string name="serviceEnabledFor" msgid="6856228140453471041">"Usluga je omogućena za:"</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Usluga je onemogućena."</string>
+    <string name="serviceRegistered" msgid="6275019082598102493">"Registracija je uspješno izvršena."</string>
+    <string name="serviceErased" msgid="1288584695297200972">"Brisanje je uspješno izvršeno."</string>
+    <string name="passwordIncorrect" msgid="7612208839450128715">"Netačna lozinka."</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"MMI kôd izvršen."</string>
+    <string name="badPin" msgid="9015277645546710014">"Stari PIN koji ste unijeli nije ispravan."</string>
+    <string name="badPuk" msgid="5487257647081132201">"PUK koji ste unijeli nije ispravan."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"PIN-ovi koje ste unijeli se ne podudaraju."</string>
+    <string name="invalidPin" msgid="3850018445187475377">"Unesite PIN koji sadrži 4 do 8 brojeva."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"Unesite PUK koji sadrži 8 ili više brojeva."</string>
+    <string name="needPuk" msgid="919668385956251611">"SIM kartica je zaključana PUK-om. Unesite PUK kôd za otključavanje kartice."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"Unesite PUK2 kako biste deblokirali SIM karticu."</string>
+    <string name="enablePin" msgid="209412020907207950">"Nije uspjelo. Prvo omogućite SIM/RUIM zaključavanje."</string>
+    <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582">
+      <item quantity="one">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj prije nego se SIM kartica zaključa.</item>
+      <item quantity="few">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja prije nego se SIM kartica zaključa.</item>
+      <item quantity="other">Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaja prije nego se SIM kartica zaključa.</item>
+    </plurals>
+    <string name="imei" msgid="2625429890869005782">"IMEI"</string>
+    <string name="meid" msgid="4841221237681254195">"MEID"</string>
+    <string name="ClipMmi" msgid="6952821216480289285">"ID dolaznog poziva"</string>
+    <string name="ClirMmi" msgid="7784673673446833091">"ID odlaznog poziva"</string>
+    <string name="ColpMmi" msgid="3065121483740183974">"Identifikacija povezane linije"</string>
+    <string name="ColrMmi" msgid="4996540314421889589">"Ograničenje identifikacije povezane linije"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"Preusmjeravanje poziva"</string>
+    <string name="CwMmi" msgid="9129678056795016867">"Poziv na čekanju"</string>
+    <string name="BaMmi" msgid="455193067926770581">"Zabrana poziva"</string>
+    <string name="PwdMmi" msgid="7043715687905254199">"Promjena lozinke"</string>
+    <string name="PinMmi" msgid="3113117780361190304">"Promjena PIN-a"</string>
+    <string name="CnipMmi" msgid="3110534680557857162">"Broj pozivaoca dostupan"</string>
+    <string name="CnirMmi" msgid="3062102121430548731">"Broj pozivaoca zabranjen"</string>
+    <string name="ThreeWCMmi" msgid="9051047170321190368">"Poziv između tri osobe"</string>
+    <string name="RuacMmi" msgid="7827887459138308886">"Odbijanje neželjenih i dosadnih poziva"</string>
+    <string name="CndMmi" msgid="3116446237081575808">"Isporuka broja pozivaoca"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Ne ometaj"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Prikaz ID-a pozivaoca u zadanim postavkama zabranjen. Sljedeći poziv: zabranjen"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Prikaz ID-a pozivaoca u zadanim postavkama zabranjen. Sljedeći poziv: nije zabranjen"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: zabranjen"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: nije zabranjen"</string>
+    <string name="serviceNotProvisioned" msgid="8614830180508686666">"Uslugu nije moguće koristiti."</string>
+    <string name="CLIRPermanent" msgid="3377371145926835671">"Ne možete promijeniti postavke ID-a pozivaoca."</string>
+    <string name="RestrictedChangedTitle" msgid="5592189398956187498">"Promijenjen ograničen pristup"</string>
+    <string name="RestrictedOnData" msgid="8653794784690065540">"Usluga prijenosa podataka je blokirana."</string>
+    <string name="RestrictedOnEmergency" msgid="6581163779072833665">"Hitni pozivi su blokirani."</string>
+    <string name="RestrictedOnNormal" msgid="4953867011389750673">"Govorne usluge su blokirane."</string>
+    <string name="RestrictedOnAllVoice" msgid="3396963652108151260">"Sve govorne usluge su blokirane."</string>
+    <string name="RestrictedOnSms" msgid="8314352327461638897">"SMS usluga je blokirana."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"Blokirane su govorne usluge i usluge prijenosa podataka."</string>
+    <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"Blokirane su govorne/SMS usluge."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"Blokirane su sve govorne i SMS usluge te usluge prijenosa podataka."</string>
+    <string name="peerTtyModeFull" msgid="6165351790010341421">"Ravnopravni uređaj zatražio TTY PUNI način rada"</string>
+    <string name="peerTtyModeHco" msgid="5728602160669216784">"Ravnopravni uređaj zatražio TTY HCO način rada"</string>
+    <string name="peerTtyModeVco" msgid="1742404978686538049">"Ravnopravni uređaj zatražio TTY VCO način rada"</string>
+    <string name="peerTtyModeOff" msgid="3280819717850602205">"Ravnopravni uređaj zatražio TTY ISKLJUČENI način rada"</string>
+    <string name="serviceClassVoice" msgid="1258393812335258019">"Govorna"</string>
+    <string name="serviceClassData" msgid="872456782077937893">"Podatke"</string>
+    <string name="serviceClassFAX" msgid="5566624998840486475">"Faks"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassDataAsync" msgid="4523454783498551468">"Asinhroni"</string>
+    <string name="serviceClassDataSync" msgid="7530000519646054776">"Sinhroni"</string>
+    <string name="serviceClassPacket" msgid="6991006557993423453">"Paket"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="roamingText0" msgid="7170335472198694945">"Uključen pokazatelj da je uređaj u roamingu"</string>
+    <string name="roamingText1" msgid="5314861519752538922">"Isključen pokazatelj da je uređaj u roamingu"</string>
+    <string name="roamingText2" msgid="8969929049081268115">"Pokazatelj da je uređaj u roamingu treperi"</string>
+    <string name="roamingText3" msgid="5148255027043943317">"Izvan naselja"</string>
+    <string name="roamingText4" msgid="8808456682550796530">"Izvan zgrade"</string>
+    <string name="roamingText5" msgid="7604063252850354350">"Roaming - preferirani sistem"</string>
+    <string name="roamingText6" msgid="2059440825782871513">"Roaming - sistem dostupan"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Roaming - udruženi partner"</string>
+    <string name="roamingText8" msgid="5989569778604089291">"Roaming - premium partner"</string>
+    <string name="roamingText9" msgid="7969296811355152491">"Roaming - sve usluge potpuno dostupne"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - djelimična funkcionalnost usluga"</string>
+    <string name="roamingText11" msgid="4154476854426920970">"Oznaka da je uređaj u roamingu uključena"</string>
+    <string name="roamingText12" msgid="1189071119992726320">"Oznaka da je uređaj u roamingu ugašena"</string>
+    <string name="roamingTextSearching" msgid="8360141885972279963">"Traženje usluge"</string>
+    <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi pozivanje"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
   </string-array>
-    <!-- no translation found for wfcSpnFormat (8211621332478306568) -->
-    <skip />
-    <!-- no translation found for wfcDataSpnFormat (1118052028767666883) -->
-    <skip />
-    <!-- no translation found for wifi_calling_off_summary (8720659586041656098) -->
-    <skip />
-    <!-- no translation found for wfc_mode_wifi_preferred_summary (1994113411286935263) -->
-    <skip />
-    <!-- no translation found for wfc_mode_cellular_preferred_summary (5920549484600758786) -->
-    <skip />
-    <!-- no translation found for wfc_mode_wifi_only_summary (2379919155237869320) -->
-    <skip />
-    <!-- no translation found for cfTemplateNotForwarded (1683685883841272560) -->
-    <skip />
-    <!-- no translation found for cfTemplateForwarded (1302922117498590521) -->
-    <skip />
-    <!-- no translation found for cfTemplateForwardedTime (9206251736527085256) -->
-    <skip />
-    <!-- no translation found for cfTemplateRegistered (5073237827620166285) -->
-    <skip />
-    <!-- no translation found for cfTemplateRegisteredTime (6781621964320635172) -->
-    <skip />
-    <!-- no translation found for fcComplete (3118848230966886575) -->
-    <skip />
-    <!-- no translation found for fcError (3327560126588500777) -->
-    <skip />
-    <!-- no translation found for httpErrorOk (1191919378083472204) -->
-    <skip />
-    <!-- no translation found for httpError (7956392511146698522) -->
-    <skip />
-    <!-- no translation found for httpErrorLookup (4711687456111963163) -->
-    <skip />
-    <!-- no translation found for httpErrorUnsupportedAuthScheme (6299980280442076799) -->
-    <skip />
-    <!-- no translation found for httpErrorAuth (1435065629438044534) -->
-    <skip />
-    <!-- no translation found for httpErrorProxyAuth (1788207010559081331) -->
-    <skip />
-    <!-- no translation found for httpErrorConnect (8714273236364640549) -->
-    <skip />
-    <!-- no translation found for httpErrorIO (2340558197489302188) -->
-    <skip />
-    <!-- no translation found for httpErrorTimeout (4743403703762883954) -->
-    <skip />
-    <!-- no translation found for httpErrorRedirectLoop (8679596090392779516) -->
-    <skip />
-    <!-- no translation found for httpErrorUnsupportedScheme (5015730812906192208) -->
-    <skip />
-    <!-- no translation found for httpErrorFailedSslHandshake (96549606000658641) -->
-    <skip />
-    <!-- no translation found for httpErrorBadUrl (3636929722728881972) -->
-    <skip />
-    <!-- no translation found for httpErrorFile (2170788515052558676) -->
-    <skip />
-    <!-- no translation found for httpErrorFileNotFound (6203856612042655084) -->
-    <skip />
-    <!-- no translation found for httpErrorTooManyRequests (1235396927087188253) -->
-    <skip />
-    <!-- no translation found for notification_title (8967710025036163822) -->
-    <skip />
-    <!-- no translation found for contentServiceSync (8353523060269335667) -->
-    <skip />
-    <!-- no translation found for contentServiceSyncNotificationTitle (397743349191901458) -->
-    <skip />
-    <!-- no translation found for contentServiceTooManyDeletesNotificationDesc (8100981435080696431) -->
-    <skip />
-    <!-- no translation found for low_memory (6494019234102154896) -->
-    <skip />
-    <!-- no translation found for low_memory (4415914910770005166) -->
-    <skip />
-    <!-- no translation found for low_memory (516619861191025923) -->
-    <skip />
-    <!-- no translation found for low_memory (3475999286680000541) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_warning (5848402127455021714) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_by_unknown (4475437862189850602) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_by_administrator (550758088185764312) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_noti_managed (4030263497686867141) -->
-    <skip />
-    <!-- no translation found for work_profile_deleted (5005572078641980632) -->
-    <skip />
-    <!-- no translation found for work_profile_deleted_description (6305147513054341102) -->
-    <skip />
-    <!-- no translation found for work_profile_deleted_details (226615743462361248) -->
-    <skip />
-    <!-- no translation found for work_profile_deleted_description_dpm_wipe (6019770344820507579) -->
-    <skip />
-    <!-- no translation found for factory_reset_warning (5423253125642394387) -->
-    <skip />
-    <!-- no translation found for factory_reset_message (4905025204141900666) -->
-    <skip />
-    <!-- no translation found for me (6545696007631404292) -->
-    <skip />
-    <!-- no translation found for power_dialog (8545351420865202853) -->
-    <skip />
-    <!-- no translation found for power_dialog (6153888706430556356) -->
-    <skip />
-    <!-- no translation found for power_dialog (1319919075463988638) -->
-    <skip />
-    <!-- no translation found for silent_mode (7167703389802618663) -->
-    <skip />
-    <!-- no translation found for turn_on_radio (3912793092339962371) -->
-    <skip />
-    <!-- no translation found for turn_off_radio (8198784949987062346) -->
-    <skip />
-    <!-- no translation found for screen_lock (799094655496098153) -->
-    <skip />
-    <!-- no translation found for power_off (4266614107412865048) -->
-    <skip />
-    <!-- no translation found for silent_mode_silent (319298163018473078) -->
-    <skip />
-    <!-- no translation found for silent_mode_vibrate (7072043388581551395) -->
-    <skip />
-    <!-- no translation found for silent_mode_ring (8592241816194074353) -->
-    <skip />
-    <!-- no translation found for reboot_to_update_title (6212636802536823850) -->
-    <skip />
-    <!-- no translation found for reboot_to_update_prepare (6305853831955310890) -->
-    <skip />
-    <!-- no translation found for reboot_to_update_package (3871302324500927291) -->
-    <skip />
-    <!-- no translation found for reboot_to_update_reboot (6428441000951565185) -->
-    <skip />
-    <!-- no translation found for reboot_to_reset_title (4142355915340627490) -->
-    <skip />
-    <!-- no translation found for reboot_to_reset_message (2432077491101416345) -->
-    <skip />
-    <!-- no translation found for shutdown_progress (2281079257329981203) -->
-    <skip />
-    <!-- no translation found for shutdown_confirm (3385745179555731470) -->
-    <skip />
-    <!-- no translation found for shutdown_confirm (476672373995075359) -->
-    <skip />
-    <!-- no translation found for shutdown_confirm (3490275567476369184) -->
-    <skip />
-    <!-- no translation found for shutdown_confirm (649792175242821353) -->
-    <skip />
-    <!-- no translation found for shutdown_confirm_question (2906544768881136183) -->
-    <skip />
-    <!-- no translation found for reboot_safemode_title (7054509914500140361) -->
-    <skip />
-    <!-- no translation found for reboot_safemode_confirm (55293944502784668) -->
-    <skip />
-    <!-- no translation found for recent_tasks_title (3691764623638127888) -->
-    <skip />
-    <!-- no translation found for no_recent_tasks (8794906658732193473) -->
-    <skip />
-    <!-- no translation found for global_actions (408477140088053665) -->
-    <skip />
-    <!-- no translation found for global_actions (7240386462508182976) -->
-    <skip />
-    <!-- no translation found for global_actions (2406416831541615258) -->
-    <skip />
-    <!-- no translation found for global_action_lock (2844945191792119712) -->
-    <skip />
-    <!-- no translation found for global_action_power_off (4471879440839879722) -->
-    <skip />
-    <!-- no translation found for global_action_bug_report (7934010578922304799) -->
-    <skip />
-    <!-- no translation found for bugreport_title (2667494803742548533) -->
-    <skip />
-    <!-- no translation found for bugreport_message (398447048750350456) -->
-    <skip />
-    <!-- no translation found for bugreport_option_interactive_title (8635056131768862479) -->
-    <skip />
-    <!-- no translation found for bugreport_option_interactive_summary (8180152634022797629) -->
-    <skip />
-    <!-- no translation found for bugreport_option_full_title (6354382025840076439) -->
-    <skip />
-    <string name="bugreport_option_full_summary" msgid="6687306111256813257">"Ta opcija vam omogućava minimalno ometanje sustava kad uređaj ne reagira ili je prespor ili kada su vam potrebni svi odjeljci izvještaja. Ne izrađuje se snimka ekrana i ne možete unijeti više detalja."</string>
-    <!-- no translation found for bugreport_countdown (6878900193900090368) -->
-    <!-- no translation found for global_action_toggle_silent_mode (8219525344246810925) -->
-    <skip />
-    <!-- no translation found for global_action_silent_mode_on_status (3289841937003758806) -->
-    <skip />
-    <!-- no translation found for global_action_silent_mode_off_status (1506046579177066419) -->
-    <skip />
-    <!-- no translation found for global_actions_toggle_airplane_mode (5884330306926307456) -->
-    <skip />
-    <!-- no translation found for global_actions_airplane_mode_on_status (2719557982608919750) -->
-    <skip />
-    <!-- no translation found for global_actions_airplane_mode_off_status (5075070442854490296) -->
-    <skip />
-    <!-- no translation found for global_action_settings (1756531602592545966) -->
-    <skip />
-    <!-- no translation found for global_action_assist (3892832961594295030) -->
-    <skip />
-    <!-- no translation found for global_action_voice_assist (7751191495200504480) -->
-    <skip />
-    <!-- no translation found for global_action_lockdown (8751542514724332873) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_info_overflow (5301981741705354993) -->
-    <skip />
-    <!-- no translation found for notification_children_count_bracketed (1769425473168347839) -->
-    <skip />
-    <!-- no translation found for notification_hidden_text (1135169301897151909) -->
-    <skip />
+    <string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string>
+    <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string>
+    <string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
+    <string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
+    <string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Prednost ima mobilna mreža"</string>
+    <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Samo Wi-Fi"</string>
+    <string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
+    <string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+    <string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> za <xliff:g id="TIME_DELAY">{2}</xliff:g> sekundi"</string>
+    <string name="cfTemplateRegistered" msgid="5073237827620166285">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Nije proslijeđen"</string>
+    <string name="cfTemplateRegisteredTime" msgid="6781621964320635172">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Poziv nije proslijeđen"</string>
+    <string name="fcComplete" msgid="3118848230966886575">"Kôd za posebne usluge potpun."</string>
+    <string name="fcError" msgid="3327560126588500777">"Problem sa povezivanjem ili nevažeći kôd za posebne usluge."</string>
+    <string name="httpErrorOk" msgid="1191919378083472204">"Uredu"</string>
+    <string name="httpError" msgid="7956392511146698522">"Došlo je do greške na mreži."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"Pronalaženje URL-a nije uspjelo."</string>
+    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"Shema za provjeru vjerodostojnosti stranice nije podržana."</string>
+    <string name="httpErrorAuth" msgid="1435065629438044534">"Došlo je do greške prilikom provjere vjerodostojnosti."</string>
+    <string name="httpErrorProxyAuth" msgid="1788207010559081331">"Došlo je do greške prilikom provjere vjerodostojnosti preko proksi servera."</string>
+    <string name="httpErrorConnect" msgid="8714273236364640549">"Povezivanje sa serverom nije uspjelo."</string>
+    <string name="httpErrorIO" msgid="2340558197489302188">"Veza sa serverom nije uspostavljena. Pokušajte ponovo kasnije."</string>
+    <string name="httpErrorTimeout" msgid="4743403703762883954">"Vrijeme za uspostavljanje veze sa serverom je isteklo."</string>
+    <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"Stranica sadrži prevelik broj preusmjeravanja na server."</string>
+    <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"Protokol nije podržan."</string>
+    <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"Uspostavljanje sigurne veze nije uspjelo."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"Greška pri otvaranju stranice zbog neispravnog URL-a."</string>
+    <string name="httpErrorFile" msgid="2170788515052558676">"Pristupanje fajlu nije uspjelo."</string>
+    <string name="httpErrorFileNotFound" msgid="6203856612042655084">"Pronalaženje traženog fajla nije uspjelo."</string>
+    <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Trenutno se obrađuje previše zahtjeva. Pokušajte ponovo kasnije."</string>
+    <string name="notification_title" msgid="8967710025036163822">"Greška u prijavi za račun <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+    <string name="contentServiceSync" msgid="8353523060269335667">"Sinhroniziranje"</string>
+    <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Sinhroniziranje"</string>
+    <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Obrisano previše unosa aplikacije <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+    <string name="low_memory" product="tablet" msgid="6494019234102154896">"Pohrana tableta je puna. Izbrišite fajlove kako biste oslobodili prostor."</string>
+    <string name="low_memory" product="watch" msgid="4415914910770005166">"Prostor za gledanje je pun. Obrišite neke fajlove da oslobodite prostor."</string>
+    <string name="low_memory" product="tv" msgid="516619861191025923">"Prostor TV-a za pohranu je pun. Obrišite neke fajlove da oslobodite prostor."</string>
+    <string name="low_memory" product="default" msgid="3475999286680000541">"Pohrana telefona je puna. Izbrišite fajlove kako biste oslobodili prostor."</string>
+    <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"Mreža može biti nadzirana"</string>
+    <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"Od nepoznate treće strane"</string>
+    <string name="ssl_ca_cert_noti_by_administrator" msgid="550758088185764312">"od strane administratora vašeg profila za posao"</string>
+    <string name="ssl_ca_cert_noti_managed" msgid="4030263497686867141">"Od <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
+    <string name="work_profile_deleted" msgid="5005572078641980632">"Poslovni profil je obrisan"</string>
+    <string name="work_profile_deleted_description" msgid="6305147513054341102">"Poslovni profil je obrisan jer nedostaje aplikacija administratora."</string>
+    <string name="work_profile_deleted_details" msgid="226615743462361248">"Aplikacija administratora za poslovni profil nedostaje ili je neispravna. Zbog toga su vaš poslovni profil i vezani podaci obrisani. Za pomoć se obratite administratoru."</string>
+    <string name="work_profile_deleted_description_dpm_wipe" msgid="6019770344820507579">"Profil za posao više nije dostupan na ovom uređaju."</string>
+    <string name="factory_reset_warning" msgid="5423253125642394387">"Uređaj će biti izbrisan"</string>
+    <string name="factory_reset_message" msgid="4905025204141900666">"Aplikaciji administratora nedostaju komponente ili je neispravna, i ne može se koristiti. Vaš uređaj će sada biti izbrisan. Za pomoć se obratite administratoru."</string>
+    <string name="me" msgid="6545696007631404292">"Ja"</string>
+    <string name="power_dialog" product="tablet" msgid="8545351420865202853">"Opcije tableta"</string>
+    <string name="power_dialog" product="tv" msgid="6153888706430556356">"Opcije za TV"</string>
+    <string name="power_dialog" product="default" msgid="1319919075463988638">"Opcije telefona"</string>
+    <string name="silent_mode" msgid="7167703389802618663">"Nečujni način rada"</string>
+    <string name="turn_on_radio" msgid="3912793092339962371">"Uključi bežičnu vezu"</string>
+    <string name="turn_off_radio" msgid="8198784949987062346">"Isključi bežičnu vezu"</string>
+    <string name="screen_lock" msgid="799094655496098153">"Zaključavanje ekrana"</string>
+    <string name="power_off" msgid="4266614107412865048">"Isključi telefon"</string>
+    <string name="silent_mode_silent" msgid="319298163018473078">"Zvuk zvona isključen"</string>
+    <string name="silent_mode_vibrate" msgid="7072043388581551395">"Zvuk zvona na vibraciji"</string>
+    <string name="silent_mode_ring" msgid="8592241816194074353">"Zvuk zvona uključen"</string>
+    <string name="reboot_to_update_title" msgid="6212636802536823850">"Ažuriranje sistema Android"</string>
+    <string name="reboot_to_update_prepare" msgid="6305853831955310890">"Priprema za ažuriranje..."</string>
+    <string name="reboot_to_update_package" msgid="3871302324500927291">"Obrađuje se paket ažuriranja..."</string>
+    <string name="reboot_to_update_reboot" msgid="6428441000951565185">"Ponovno se pokreće..."</string>
+    <string name="reboot_to_reset_title" msgid="4142355915340627490">"Vraćanje na tvorničke postavke"</string>
+    <string name="reboot_to_reset_message" msgid="2432077491101416345">"Ponovno se pokreće..."</string>
+    <string name="shutdown_progress" msgid="2281079257329981203">"Gašenje u toku…"</string>
+    <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Vaš tablet će se isključiti."</string>
+    <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"TV će se isključiti."</string>
+    <string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Sat će se isključiti."</string>
+    <string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon će se isključiti."</string>
+    <string name="shutdown_confirm_question" msgid="2906544768881136183">"Želite li ugasiti telefon?"</string>
+    <string name="reboot_safemode_title" msgid="7054509914500140361">"Ponovo pokreni uređaj u sigurnom načinu rada"</string>
+    <string name="reboot_safemode_confirm" msgid="55293944502784668">"Želite li pokrenuti uređaj u sigurnom načinu rada? To će onemogućiti sve aplikacije trećih strana koje ste instalirali. One će biti obnovljene kada ponovo pokrenete uređaj."</string>
+    <string name="recent_tasks_title" msgid="3691764623638127888">"Nedavni zadaci"</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Nema nedavno pokrenutih aplikacija."</string>
+    <string name="global_actions" product="tablet" msgid="408477140088053665">"Opcije tableta"</string>
+    <string name="global_actions" product="tv" msgid="7240386462508182976">"Opcije za TV"</string>
+    <string name="global_actions" product="default" msgid="2406416831541615258">"Opcije telefona"</string>
+    <string name="global_action_lock" msgid="2844945191792119712">"Zaključavanje ekrana"</string>
+    <string name="global_action_power_off" msgid="4471879440839879722">"Isključi telefon"</string>
+    <string name="global_action_bug_report" msgid="7934010578922304799">"Izvještaj o greškama"</string>
+    <string name="bugreport_title" msgid="2667494803742548533">"Kreirajte izvještaj o greškama"</string>
+    <string name="bugreport_message" msgid="398447048750350456">"Ovim će se prikupljati informacije o trenutnom stanju uređaja, koji će biti poslani kao poruka e-pošte. Može malo potrajati dok se izvještaj o greškama ne kreira i bude spreman za slanje. Budite strpljivi."</string>
+    <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Interaktivni izvještaj"</string>
+    <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"Koristite ovo u većini slučajeva. Omogućava vam praćenje progresa izvještaja i unošenje više detalja o datom problemu. Neke manje korištene oblasti za čiji izvještaj je potrebno mnogo vremena mogu biti izostavljene."</string>
+    <string name="bugreport_option_full_title" msgid="6354382025840076439">"Kompletan izvještaj"</string>
+    <string name="bugreport_option_full_summary" msgid="6687306111256813257">"Koristite ovu opciju za minimalno ometanje sistema kad uređaj ne reaguje ili je prespor, ili kada su vam potrebni svi odjeljci izvještaja. Opcija ne uzima snimku ekrana i ne dozvoljava unošenje više detalja."</string>
+    <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
+      <item quantity="one">Snimak ekrana za prijavu greške pravim za <xliff:g id="NUMBER_1">%d</xliff:g> sekundu.</item>
+      <item quantity="few">Snimak ekrana za prijavu greške pravim za <xliff:g id="NUMBER_1">%d</xliff:g> sekunde.</item>
+      <item quantity="other">Snimak ekrana za prijavu greške pravim za <xliff:g id="NUMBER_1">%d</xliff:g> sekundi.</item>
+    </plurals>
+    <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Nečujni način rada"</string>
+    <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je isključen"</string>
+    <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je uključen"</string>
+    <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Način rada u avionu"</string>
+    <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Uključen je način rada u avionu"</string>
+    <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Način rada u avionu ugašen"</string>
+    <string name="global_action_settings" msgid="1756531602592545966">"Postavke"</string>
+    <string name="global_action_assist" msgid="3892832961594295030">"Pomoć"</string>
+    <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string>
+    <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj odmah"</string>
+    <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
+    <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string>
+    <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je sakriven"</string>
     <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj skriven u skladu sa pravilima"</string>
-    <!-- no translation found for safeMode (2788228061547930246) -->
-    <skip />
-    <!-- no translation found for android_system_label (6577375335728551336) -->
-    <skip />
-    <!-- no translation found for user_owner_label (2804351898001038951) -->
-    <skip />
-    <!-- no translation found for managed_profile_label (6260850669674791528) -->
-    <skip />
-    <!-- no translation found for permgrouplab_contacts (3657758145679177612) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_contacts (6951499528303668046) -->
-    <skip />
-    <!-- no translation found for permgrouplab_location (7275582855722310164) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_location (1346617465127855033) -->
-    <skip />
-    <!-- no translation found for permgrouplab_calendar (5863508437783683902) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_calendar (3889615280211184106) -->
-    <skip />
-    <!-- no translation found for permgrouplab_sms (228308803364967808) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_sms (4656988620100940350) -->
-    <skip />
-    <!-- no translation found for permgrouplab_storage (1971118770546336966) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (637758554581589203) -->
-    <skip />
-    <!-- no translation found for permgrouplab_microphone (171539900250043464) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_microphone (4988812113943554584) -->
-    <skip />
-    <!-- no translation found for permgrouplab_camera (4820372495894586615) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_camera (3250611594678347720) -->
-    <skip />
-    <!-- no translation found for permgrouplab_phone (5229115638567440675) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_phone (6234224354060641055) -->
-    <skip />
-    <!-- no translation found for permgrouplab_sensors (416037179223226722) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_sensors (7147968539346634043) -->
-    <skip />
-    <!-- no translation found for capability_title_canRetrieveWindowContent (3901717936930170320) -->
-    <skip />
-    <!-- no translation found for capability_desc_canRetrieveWindowContent (3772225008605310672) -->
-    <skip />
-    <!-- no translation found for capability_title_canRequestTouchExploration (3108723364676667320) -->
-    <skip />
-    <!-- no translation found for capability_desc_canRequestTouchExploration (5800552516779249356) -->
-    <skip />
-    <!-- no translation found for capability_title_canRequestEnhancedWebAccessibility (1739881766522594073) -->
-    <skip />
-    <!-- no translation found for capability_desc_canRequestEnhancedWebAccessibility (7881063961507511765) -->
-    <skip />
-    <!-- no translation found for capability_title_canRequestFilterKeyEvents (2103440391902412174) -->
-    <skip />
-    <!-- no translation found for capability_desc_canRequestFilterKeyEvents (7463135292204152818) -->
-    <skip />
-    <!-- no translation found for capability_title_canControlMagnification (3593493281059424855) -->
-    <skip />
-    <!-- no translation found for capability_desc_canControlMagnification (4791858203568383773) -->
-    <skip />
-    <!-- no translation found for capability_title_canPerformGestures (7418984730362576862) -->
-    <skip />
-    <!-- no translation found for capability_desc_canPerformGestures (8296373021636981249) -->
-    <skip />
-    <!-- no translation found for permlab_statusBar (7417192629601890791) -->
-    <skip />
-    <!-- no translation found for permdesc_statusBar (8434669549504290975) -->
-    <skip />
-    <!-- no translation found for permlab_statusBarService (4826835508226139688) -->
-    <skip />
-    <!-- no translation found for permdesc_statusBarService (716113660795976060) -->
-    <skip />
-    <!-- no translation found for permlab_expandStatusBar (1148198785937489264) -->
-    <skip />
-    <!-- no translation found for permdesc_expandStatusBar (6917549437129401132) -->
-    <skip />
-    <!-- no translation found for permlab_install_shortcut (4279070216371564234) -->
-    <skip />
-    <!-- no translation found for permdesc_install_shortcut (8341295916286736996) -->
-    <skip />
-    <!-- no translation found for permlab_uninstall_shortcut (4729634524044003699) -->
-    <skip />
-    <!-- no translation found for permdesc_uninstall_shortcut (6745743474265057975) -->
-    <skip />
-    <!-- no translation found for permlab_processOutgoingCalls (3906007831192990946) -->
-    <skip />
-    <!-- no translation found for permdesc_processOutgoingCalls (5156385005547315876) -->
-    <skip />
-    <!-- no translation found for permlab_receiveSms (8673471768947895082) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveSms (6424387754228766939) -->
-    <skip />
-    <!-- no translation found for permlab_receiveMms (1821317344668257098) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveMms (533019437263212260) -->
-    <skip />
-    <!-- no translation found for permlab_readCellBroadcasts (1598328843619646166) -->
-    <skip />
-    <!-- no translation found for permdesc_readCellBroadcasts (6361972776080458979) -->
-    <skip />
-    <!-- no translation found for permlab_subscribedFeedsRead (4756609637053353318) -->
-    <skip />
-    <!-- no translation found for permdesc_subscribedFeedsRead (5557058907906144505) -->
-    <skip />
-    <!-- no translation found for permlab_sendSms (7544599214260982981) -->
-    <skip />
-    <!-- no translation found for permdesc_sendSms (7094729298204937667) -->
-    <skip />
-    <!-- no translation found for permlab_readSms (8745086572213270480) -->
-    <skip />
-    <!-- no translation found for permdesc_readSms (2467981548684735522) -->
-    <skip />
-    <!-- no translation found for permdesc_readSms (5102425513647038535) -->
-    <skip />
-    <!-- no translation found for permdesc_readSms (3695967533457240550) -->
-    <skip />
-    <!-- no translation found for permlab_receiveWapPush (5991398711936590410) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveWapPush (748232190220583385) -->
-    <skip />
-    <!-- no translation found for permlab_getTasks (6466095396623933906) -->
-    <skip />
-    <!-- no translation found for permdesc_getTasks (7454215995847658102) -->
-    <skip />
-    <!-- no translation found for permlab_manageProfileAndDeviceOwners (7918181259098220004) -->
-    <skip />
-    <!-- no translation found for permdesc_manageProfileAndDeviceOwners (106894851498657169) -->
-    <skip />
-    <!-- no translation found for permlab_reorderTasks (2018575526934422779) -->
-    <skip />
-    <!-- no translation found for permdesc_reorderTasks (7734217754877439351) -->
-    <skip />
-    <!-- no translation found for permlab_enableCarMode (5684504058192921098) -->
-    <skip />
-    <!-- no translation found for permdesc_enableCarMode (4853187425751419467) -->
-    <skip />
-    <!-- no translation found for permlab_killBackgroundProcesses (3914026687420177202) -->
-    <skip />
-    <!-- no translation found for permdesc_killBackgroundProcesses (4593353235959733119) -->
-    <skip />
-    <!-- no translation found for permlab_systemAlertWindow (3543347980839518613) -->
-    <skip />
-    <!-- no translation found for permdesc_systemAlertWindow (8584678381972820118) -->
-    <skip />
-    <!-- no translation found for permlab_persistentActivity (8841113627955563938) -->
-    <skip />
-    <!-- no translation found for permdesc_persistentActivity (8525189272329086137) -->
-    <skip />
-    <!-- no translation found for permdesc_persistentActivity (5086862529499103587) -->
-    <skip />
-    <!-- no translation found for permdesc_persistentActivity (4384760047508278272) -->
-    <skip />
-    <!-- no translation found for permlab_getPackageSize (7472921768357981986) -->
-    <skip />
-    <!-- no translation found for permdesc_getPackageSize (3921068154420738296) -->
-    <skip />
-    <!-- no translation found for permlab_writeSettings (2226195290955224730) -->
-    <skip />
-    <!-- no translation found for permdesc_writeSettings (7775723441558907181) -->
-    <skip />
-    <!-- no translation found for permlab_receiveBootCompleted (5312965565987800025) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveBootCompleted (7390304664116880704) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveBootCompleted (4525890122209673621) -->
-    <skip />
-    <!-- no translation found for permdesc_receiveBootCompleted (513950589102617504) -->
-    <skip />
-    <!-- no translation found for permlab_broadcastSticky (7919126372606881614) -->
-    <skip />
-    <!-- no translation found for permdesc_broadcastSticky (7749760494399915651) -->
-    <skip />
-    <!-- no translation found for permdesc_broadcastSticky (6839285697565389467) -->
-    <skip />
-    <!-- no translation found for permdesc_broadcastSticky (2825803764232445091) -->
-    <skip />
-    <!-- no translation found for permlab_readContacts (8348481131899886131) -->
-    <skip />
-    <!-- no translation found for permdesc_readContacts (5294866856941149639) -->
-    <skip />
-    <!-- no translation found for permdesc_readContacts (1839238344654834087) -->
-    <skip />
-    <!-- no translation found for permdesc_readContacts (8440654152457300662) -->
-    <skip />
-    <!-- no translation found for permlab_writeContacts (5107492086416793544) -->
-    <skip />
-    <!-- no translation found for permdesc_writeContacts (897243932521953602) -->
-    <skip />
-    <!-- no translation found for permdesc_writeContacts (5438230957000018959) -->
-    <skip />
-    <!-- no translation found for permdesc_writeContacts (589869224625163558) -->
-    <skip />
-    <!-- no translation found for permlab_readCallLog (3478133184624102739) -->
-    <skip />
-    <!-- no translation found for permdesc_readCallLog (3700645184870760285) -->
-    <skip />
-    <!-- no translation found for permdesc_readCallLog (5611770887047387926) -->
-    <skip />
-    <!-- no translation found for permdesc_readCallLog (5777725796813217244) -->
-    <skip />
-    <!-- no translation found for permlab_writeCallLog (8552045664743499354) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCallLog (6661806062274119245) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCallLog (4225034892248398019) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCallLog (683941736352787842) -->
-    <skip />
-    <!-- no translation found for permlab_bodySensors (4683341291818520277) -->
-    <skip />
-    <!-- no translation found for permdesc_bodySensors (4380015021754180431) -->
-    <skip />
-    <!-- no translation found for permlab_readCalendar (5972727560257612398) -->
-    <skip />
-    <!-- no translation found for permdesc_readCalendar (4216462049057658723) -->
-    <skip />
-    <!-- no translation found for permdesc_readCalendar (3191352452242394196) -->
-    <skip />
-    <!-- no translation found for permdesc_readCalendar (7434548682470851583) -->
-    <skip />
-    <!-- no translation found for permlab_writeCalendar (8438874755193825647) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCalendar (6679035520113668528) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCalendar (1273290605500902507) -->
-    <skip />
-    <!-- no translation found for permdesc_writeCalendar (2324469496327249376) -->
-    <skip />
-    <!-- no translation found for permlab_accessLocationExtraCommands (2836308076720553837) -->
-    <skip />
-    <!-- no translation found for permdesc_accessLocationExtraCommands (6078307221056649927) -->
-    <skip />
-    <!-- no translation found for permlab_accessFineLocation (251034415460950944) -->
-    <skip />
-    <!-- no translation found for permdesc_accessFineLocation (5295047563564981250) -->
-    <skip />
-    <!-- no translation found for permlab_accessCoarseLocation (7715277613928539434) -->
-    <skip />
-    <!-- no translation found for permdesc_accessCoarseLocation (2538200184373302295) -->
-    <skip />
-    <!-- no translation found for permlab_modifyAudioSettings (6095859937069146086) -->
-    <skip />
-    <!-- no translation found for permdesc_modifyAudioSettings (3522565366806248517) -->
-    <skip />
-    <!-- no translation found for permlab_recordAudio (3876049771427466323) -->
-    <skip />
-    <!-- no translation found for permdesc_recordAudio (4906839301087980680) -->
-    <skip />
-    <!-- no translation found for permlab_sim_communication (2935852302216852065) -->
-    <skip />
-    <!-- no translation found for permdesc_sim_communication (5725159654279639498) -->
-    <skip />
-    <!-- no translation found for permlab_camera (3616391919559751192) -->
-    <skip />
-    <!-- no translation found for permdesc_camera (8497216524735535009) -->
-    <skip />
-    <!-- no translation found for permlab_vibrate (7696427026057705834) -->
-    <skip />
-    <!-- no translation found for permdesc_vibrate (6284989245902300945) -->
-    <skip />
-    <!-- no translation found for permlab_callPhone (3925836347681847954) -->
-    <skip />
-    <!-- no translation found for permdesc_callPhone (3740797576113760827) -->
-    <skip />
-    <!-- no translation found for permlab_accessImsCallService (3574943847181793918) -->
-    <skip />
-    <!-- no translation found for permdesc_accessImsCallService (8992884015198298775) -->
-    <skip />
-    <!-- no translation found for permlab_readPhoneState (9178228524507610486) -->
-    <skip />
-    <!-- no translation found for permdesc_readPhoneState (1639212771826125528) -->
-    <skip />
-    <!-- no translation found for permlab_wakeLock (1531731435011495015) -->
-    <skip />
-    <!-- no translation found for permlab_wakeLock (2601193288949154131) -->
-    <skip />
-    <!-- no translation found for permlab_wakeLock (573480187941496130) -->
-    <skip />
-    <!-- no translation found for permdesc_wakeLock (7311319824400447868) -->
-    <skip />
-    <!-- no translation found for permdesc_wakeLock (3208534859208996974) -->
-    <skip />
-    <!-- no translation found for permdesc_wakeLock (8559100677372928754) -->
-    <skip />
-    <!-- no translation found for permlab_transmitIr (7545858504238530105) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (5358308854306529170) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (3926790828514867101) -->
-    <skip />
-    <!-- no translation found for permdesc_transmitIr (7957763745020300725) -->
-    <skip />
-    <!-- no translation found for permlab_setWallpaper (6627192333373465143) -->
-    <skip />
-    <!-- no translation found for permdesc_setWallpaper (7373447920977624745) -->
-    <skip />
-    <!-- no translation found for permlab_setWallpaperHints (3278608165977736538) -->
-    <skip />
-    <!-- no translation found for permdesc_setWallpaperHints (8235784384223730091) -->
-    <skip />
-    <!-- no translation found for permlab_setTimeZone (2945079801013077340) -->
-    <skip />
-    <!-- no translation found for permdesc_setTimeZone (1676983712315827645) -->
-    <skip />
-    <!-- no translation found for permdesc_setTimeZone (888864653946175955) -->
-    <skip />
-    <!-- no translation found for permdesc_setTimeZone (4499943488436633398) -->
-    <skip />
-    <!-- no translation found for permlab_getAccounts (1086795467760122114) -->
-    <skip />
-    <!-- no translation found for permdesc_getAccounts (2741496534769660027) -->
-    <skip />
-    <!-- no translation found for permdesc_getAccounts (4190633395633907543) -->
-    <skip />
-    <!-- no translation found for permdesc_getAccounts (3448316822451807382) -->
-    <skip />
-    <!-- no translation found for permlab_accessNetworkState (4951027964348974773) -->
-    <skip />
-    <!-- no translation found for permdesc_accessNetworkState (8318964424675960975) -->
-    <skip />
-    <!-- no translation found for permlab_createNetworkSockets (7934516631384168107) -->
-    <skip />
-    <!-- no translation found for permdesc_createNetworkSockets (3403062187779724185) -->
-    <skip />
-    <!-- no translation found for permlab_changeNetworkState (958884291454327309) -->
-    <skip />
-    <!-- no translation found for permdesc_changeNetworkState (6789123912476416214) -->
-    <skip />
-    <!-- no translation found for permlab_changeTetherState (5952584964373017960) -->
-    <skip />
-    <!-- no translation found for permdesc_changeTetherState (1524441344412319780) -->
-    <skip />
-    <!-- no translation found for permlab_accessWifiState (5202012949247040011) -->
-    <skip />
-    <!-- no translation found for permdesc_accessWifiState (5002798077387803726) -->
-    <skip />
-    <!-- no translation found for permlab_changeWifiState (6550641188749128035) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWifiState (7137950297386127533) -->
-    <skip />
-    <!-- no translation found for permlab_changeWifiMulticastState (1368253871483254784) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWifiMulticastState (7969774021256336548) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWifiMulticastState (9031975661145014160) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWifiMulticastState (6851949706025349926) -->
-    <skip />
-    <!-- no translation found for permlab_bluetoothAdmin (6006967373935926659) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetoothAdmin (6921177471748882137) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetoothAdmin (3373125682645601429) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetoothAdmin (8931682159331542137) -->
-    <skip />
-    <!-- no translation found for permlab_accessWimaxState (4195907010610205703) -->
-    <skip />
-    <!-- no translation found for permdesc_accessWimaxState (6360102877261978887) -->
-    <skip />
-    <!-- no translation found for permlab_changeWimaxState (340465839241528618) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWimaxState (3156456504084201805) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWimaxState (6022307083934827718) -->
-    <skip />
-    <!-- no translation found for permdesc_changeWimaxState (697025043004923798) -->
-    <skip />
-    <!-- no translation found for permlab_bluetooth (6127769336339276828) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetooth (3480722181852438628) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetooth (3974124940101104206) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetooth (3207106324452312739) -->
-    <skip />
-    <!-- no translation found for permlab_nfc (4423351274757876953) -->
-    <skip />
-    <!-- no translation found for permdesc_nfc (7120611819401789907) -->
-    <skip />
-    <!-- no translation found for permlab_disableKeyguard (3598496301486439258) -->
-    <skip />
-    <!-- no translation found for permdesc_disableKeyguard (6034203065077122992) -->
-    <skip />
-    <!-- no translation found for permlab_manageFingerprint (5640858826254575638) -->
-    <skip />
-    <!-- no translation found for permdesc_manageFingerprint (178208705828055464) -->
-    <skip />
-    <!-- no translation found for permlab_useFingerprint (3150478619915124905) -->
-    <skip />
-    <!-- no translation found for permdesc_useFingerprint (9165097460730684114) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_partial (735082772341716043) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_insufficient (4596546021310923214) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1087209702421076105) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (6470642383109155969) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_slow (59250885689661653) -->
-    <skip />
+    <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
+    <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
+    <string name="user_owner_label" msgid="2804351898001038951">"Lično"</string>
+    <string name="managed_profile_label" msgid="6260850669674791528">"Poslovni"</string>
+    <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string>
+    <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupa vašim kontaktima"</string>
+    <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
+    <string name="permgroupdesc_location" msgid="1346617465127855033">"pristupa lokaciji ovog uređaja"</string>
+    <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
+    <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupa vašem kalendaru"</string>
+    <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
+    <string name="permgroupdesc_sms" msgid="4656988620100940350">"šalje i pregleda SMS poruke"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Pohrana"</string>
+    <string name="permgroupdesc_storage" msgid="637758554581589203">"pristupa slikama, medijskim fajlovima i fajlovima na vašem uređaju"</string>
+    <string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
+    <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snima zvuk"</string>
+    <string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
+    <string name="permgroupdesc_camera" msgid="3250611594678347720">"slika i snima videozapise"</string>
+    <string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
+    <string name="permgroupdesc_phone" msgid="6234224354060641055">"poziva i upravlja pozivima"</string>
+    <string name="permgrouplab_sensors" msgid="416037179223226722">"Tjelesni senzori"</string>
+    <string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vašim vitalnim funkcijama"</string>
+    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ponovo prikaži sadržaj prozora"</string>
+    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji trenutno koristite."</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključite Istraživanje dodirom"</string>
+    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Stavke koje dotaknete će biti izgovorene naglas, a ekran možete istražiti pokretima"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Uključite poboljšanu web pristupačnost"</string>
+    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Možda će biti instalirana skripta kako bi sadržaj aplikacije bio dostupniji."</string>
+    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Obratite pažnju na tekst koji tipkate"</string>
+    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Uključuje lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
+    <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontroliranje uvećanja prikaza na ekranu"</string>
+    <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolira stepen uvećanja prikaza na ekranu i podešavanje položaja."</string>
+    <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Praviti pokrete"</string>
+    <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može dodirivati, prevlačiti, hvatati prstima i praviti druge pokrete."</string>
+    <string name="permlab_statusBar" msgid="7417192629601890791">"onemogućavanje ili mijenjanje statusne trake"</string>
+    <string name="permdesc_statusBar" msgid="8434669549504290975">"Dozvoljava aplikaciji onemogućavanje statusne trake ili dodavanje i uklanjanje sistemskih ikona."</string>
+    <string name="permlab_statusBarService" msgid="4826835508226139688">"funkcioniranje u vidu statusne trake"</string>
+    <string name="permdesc_statusBarService" msgid="716113660795976060">"Dozvoljava aplikaciji da postane statusna traka."</string>
+    <string name="permlab_expandStatusBar" msgid="1148198785937489264">"otvaranje/zatvaranje statusne trake"</string>
+    <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Dozvoljava aplikaciji otvaranje ili zatvaranje statusne trake."</string>
+    <string name="permlab_install_shortcut" msgid="4279070216371564234">"instaliranje prečica"</string>
+    <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Omogućava aplikaciji dodavanje prečice za početni ekran bez intervencije korisnika."</string>
+    <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uklanjanje prečica"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Omogućava aplikaciji uklanjanje prečice početnog ekrana bez intervencije korisnika."</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"preusmjeravanje odlaznih poziva"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Dozvoljava aplikaciji da vidi birani broj prilikom odlaznog poziva uz opciju da poziv preusmjeri na drugi broj ili da ga skroz prekine."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"primanje tekstualnih poruka (SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Omogućava aplikaciji primanje i obradu SMS poruka. Ovo znači da aplikacija može pratiti ili brisati poruke poslane na vaš uređaj, a da vam ih pritom ne prikazuje."</string>
+    <string name="permlab_receiveMms" msgid="1821317344668257098">"primanje tekstualnih poruka (MMS)"</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Omogućava aplikaciji prijem i obradu MMS poruka. Ovo znači da aplikacija može pratiti ili brisati poruke poslane na vaš uređaj, a da vam ih pritom ne prikazuje."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čitanje poruka info servisa"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Omogućava aplikaciji čitanje poruka info servisa koje je primio vaš uređaj. Upozorenja koja emitira info servis se isporučuju na nekim lokacijama kako bi vas upozorila na vanredne situacije. Zlonamjerne aplikacije mogu ometati performanse ili rad vašeg uređaja kada primite informaciju o vanrednoj situaciji od info servisa."</string>
+    <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"čitanje sadržaja na koje ste pretplaćeni"</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Dozvoljava aplikaciji prikupljanje detalja o trenutno sinhroniziranim sadržajima."</string>
+    <string name="permlab_sendSms" msgid="7544599214260982981">"slanje i pregledanje SMS poruka"</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Omogućava aplikaciji slanje SMS poruka. Ovo može dovesti do neočekivanih troškova. Zlonamjerne aplikacije mogu trošiti vaš novac tako što će slati poruke bez vašeg znanja."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"čitanje vaših tekstualnih poruka (SMS ili MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Omogućava aplikaciji čitanje SMS poruka koje su pohranjene na vašem telefonu ili SIM kartici. Ovo omogućava aplikaciji čitanje svih SMS poruka, bez obzira na njihov sadržaj ili povjerljivost."</string>
+    <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Dozvoljava aplikacijama čitanje SMS poruka pohranjenih na TV-u ili SIM kartici. Ovim se aplikaciji omogućava čitanje svih SMS poruka, bez obzira na njihov sadržaj ili povjerljivost."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Omogućava aplikaciji čitanje SMS poruka koje su pohranjene na vašem telefonu ili SIM kartici. Ovo omogućava aplikaciji čitanje svih SMS poruka, bez obzira na njihov sadržaj ili povjerljivost."</string>
+    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"primanje tekstualnih poruka (WAP)"</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Omogućava aplikaciji primanje i obradu WAP poruka. Ovo znači da aplikacija može pratiti ili brisati poruke poslane na vaš uređaj, a da vam ih pritom ne prikazuje."</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"preuzimanje informacija o pokrenutim aplikacijama"</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Omogućava aplikaciji preuzimanje informacija o trenutnim i nedavno pokrenutim zadacima. Ovo može omogućiti aplikaciji da otkrije informacije o aplikacijama korištenim na uređaju."</string>
+    <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"upravljanje vlasnicima profila i uređaja"</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Omogućava aplikaciji da postavi vlasnike profila i vlasnika uređaja."</string>
+    <string name="permlab_reorderTasks" msgid="2018575526934422779">"izmjena rasporeda pokrenutih aplikacija"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Omogućava aplikaciji pomjeranje zadataka u prvi plan i pozadinu. Aplikacija ovo može učiniti bez vašeg učešća."</string>
+    <string name="permlab_enableCarMode" msgid="5684504058192921098">"omogućavanje načina rada u autu"</string>
+    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Dozvoljava aplikaciji da omogući način rada u autu."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"zatvaranje drugih aplikacija"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Omogućava aplikaciji prekid pozadinskih procesa drugih aplikacija. Ovo može dovesti do prestanka rada drugih aplikacija."</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"crtanje preko drugih aplikacija"</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Omogućava aplikaciji crtanje po drugim aplikacijama ili dijelovima korisničkog sučelja. Ovo može ometati korištenje sučelja u bilo kojoj aplikaciji ili promijeniti ono što mislite da vidite u drugim aplikacijama."</string>
+    <string name="permlab_persistentActivity" msgid="8841113627955563938">"podešavanje aplikacije tako da je uvijek pokrenuta"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Omogućava aplikaciji da neke svoje dijelove pohrani trajno u memoriji. Ovo može ograničiti veličinu raspoložive memorije za druge aplikacije i tako usporiti tablet."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Dozvoljava aplikaciji da jednim dijelom trajno ostaje u memoriji. Time se ostalim aplikacijama dostupna memorija može ograničiti te usporiti rad TV-a."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Omogućava aplikaciji da neke svoje dijelove pohrani trajno u memoriji. Ovo može ograničiti veličinu raspoložive memorije za druge aplikacije i tako usporiti telefon."</string>
+    <string name="permlab_getPackageSize" msgid="7472921768357981986">"mjerenje prostora kojeg aplikacije zauzimaju u pohrani"</string>
+    <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Dozvoljava aplikaciji preuzimanje svog kôda, podataka i veličine keš memorije"</string>
+    <string name="permlab_writeSettings" msgid="2226195290955224730">"izmjena postavki sistema"</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Dozvoljava aplikaciji izmijenu postavki sistema. Zlonamjerne aplikacije mogu oštetiti konfiguraciju sistema."</string>
+    <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"pokrenuti pri pokretanju"</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Dozvoljava aplikaciji da se sama pokrene čim sistem završi pokretanje. Zbog toga pokretanje tableta može trajati duže i to može omogućiti aplikaciji da uspori rad čitavog tableta svojim neprekidnim radom."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Dozvoljava aplikaciji samostalno pokretanje odmah nakon pokretanja sistema. Ovim se vrijeme pokretanja TV-a može produžiti, a aplikaciji se omogućava da uspori rad tableta tako što je stalno aktivna."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Dozvoljava aplikaciji da se sama pokrene čim sistem završi pokretanje. Zbog toga pokretanje telefona može trajati duže i to može omogućiti aplikaciji da uspori rad čitavog telefona svojim neprekidnim radom."</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"slanje ljepljivih informacija"</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Omogućava aplikaciji slanje ljepljivih informacija koje ostaju nakon prestanka emitiranja. Njihova pretjerana upotreba može usporiti ili destabilizirati rad tableta jer troši previše memorije."</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="6839285697565389467">"Dozvoljava aplikaciji slanje ljepljivih informacija koje ostaju nakon prestanka emitiranja. Pretjeranom upotrebom može se usporiti ili destabilizirati rad TV-a zbog korištenja previše memorije."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Omogućava aplikaciji slanje ljepljivih informacija koje ostaju nakon prestanka emitiranja. Njihova pretjerana upotreba može usporiti ili destabilizirati rad telefona jer troši previše memorije."</string>
+    <string name="permlab_readContacts" msgid="8348481131899886131">"čitanje vaših kontakata"</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Omogućava aplikaciji čitanje podataka o kontaktima koji su pohranjeni na vašem tabletu, uključujući učestalost vaših poziva, slanja e-pošte ili nekog drugog vida komunikacije sa određenim pojedincima. Ova dozvola omogućava aplikacijama da pohrane podatke o vašim kontaktima tako da ih zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"Dozvoljava aplikaciji da čita podatke o vašim kontaktima pohranjenim na TV-u, uključujući učestalost poziva, slanja e-pošte ili komuniciranja na bilo koji način s određenim osobama. Ovom dozvolom aplikacijama se omogućava da sačuvaju podatke o kontaktima, a zlonamjerne aplikacije mogu bez vašeg znanja podijeliti ove podatke."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Omogućava aplikaciji čitanje podataka o kontaktima koji su pohranjeni na vašem telefonu, uključujući učestalost vaših poziva, slanja e-pošte ili nekog drugog vida komunikacije sa određenim pojedincima. Ova dozvola omogućava aplikacijama da pohrane podatke o vašim kontaktima tako da ih zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
+    <string name="permlab_writeContacts" msgid="5107492086416793544">"izmjena podataka o kontaktima"</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Omogućava aplikaciji da izmijeni podatke o kontaktima koji su pohranjeni na vašem tabletu, uključujući učestalost vaših poziva, slanje e-pošte, ili neki drugi vid komunikacije sa određenim kontaktima. Ova dozvola omogućava aplikaciji da obriše podatke o kontaktima."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"Dozvoljava aplikaciji izmjenu podataka o vašim kontaktima pohranjenim na TV-u, uključujući učestalost poziva, slanja e-pošte ili komuniciranja na bilo koji način s određenim kontaktima. Ovom dozvolom aplikacijama se omogućava brisanje podataka o kontaktima."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Omogućava aplikaciji da izmijeni podatke o kontaktima koji su pohranjeni na vašem telefonu, uključujući učestalost vaših poziva, slanje e-pošte, ili neki drugi vid komunikacije sa određenim kontaktima. Ova dozvola omogućava aplikaciji da izbriše podatke o kontaktima."</string>
+    <string name="permlab_readCallLog" msgid="3478133184624102739">"čitanje zapisnika poziva"</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Omogućava aplikaciji čitanje zapisnika poziva na vašem tabletu, uključujući podatke o dolaznim i odlaznim pozivima. Ova dozvola omogućava aplikacijama da pohrane vaš zapisnik poziva, a na taj način ga zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
+    <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Dozvoljava aplikaciji da čita evidenciju poziva s TV-a, uključujući podatke o dolaznim i odlaznim pozivima. Ovom dozvolom aplikacijama se omogućava da sačuvaju podatke o evidenciji poziva, a zlonamjerne aplikacije mogu bez vašeg znanja podijeliti ove podatke."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Omogućava aplikaciji čitanje zapisnika poziva na vašem telefonu, uključujući podatke o dolaznim i odlaznim pozivima. Ova dozvola omogućava aplikacijama da pohrane vaš zapisnik poziva, a na taj način ga zlonamjerne aplikacije mogu podijeliti bez vašeg znanja."</string>
+    <string name="permlab_writeCallLog" msgid="8552045664743499354">"pisanje zapisnika poziva"</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Omogućava aplikaciji da izmijeni zapisnik poziva sa vašeg tableta, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije mogu to iskoristiti za brisanje ili izmjenu vašeg zapisnika poziva."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Dozvoljava aplikaciji izmjenu evidencije poziva s TV-a, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije mogu to iskoristiti za brisanje ili izmjenu evidencije poziva."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Omogućava aplikaciji da izmijeni zapisnik poziva sa vašeg telefona, uključujući podatke o dolaznim i odlaznim pozivima. Zlonamjerne aplikacije mogu to iskoristiti za brisanje ili izmjenu vašeg zapisnika poziva."</string>
+    <string name="permlab_bodySensors" msgid="4683341291818520277">"pristup tjelesnim senzorima (poput monitora za puls)"</string>
+    <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Dozvoljava aplikaciji pristup podacima sa senzora koji prate fizičke pokazatelje kao što je vaš puls."</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"čitanje događaja iz kalendara te povjerljivih informacija"</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Omogućava aplikaciji čitanje svih događaja iz kalendara koji se nalaze na vašem tabletu, uključujući i one o prijateljima i saradnicima. Ovim se aplikaciji može omogućiti da podijeli ili pohrani vaše podatke iz kalendara, bez obzira na njihovu povjerljivost ili osjetljivost."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Dozvoljava aplikaciji da čita sve događaje iz kalendara koji su pohranjeni na TV-u, uključujući i one koji se odnose na prijatelje ili saradnike. Ovim se aplikaciji može omogućiti da podatke iz kalendara podijeli ili sačuva, bez obzira na njihovu povjerljivost ili osjetljivost."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Omogućava aplikaciji čitanje svih događaja iz kalendara koji se nalaze na vašem telefonu, uključujući i one o prijateljima i saradnicima. Ovim se aplikaciji može omogućiti da podijeli ili pohrani vaše podatke iz kalendara, bez obzira na njihovu povjerljivost ili osjetljivost."</string>
+    <string name="permlab_writeCalendar" msgid="8438874755193825647">"dodavanje ili izmjena kalendarskih događaja i slanje e-pošte gostima bez znanja vlasnika"</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Omogućava aplikaciji da doda, ukloni i promijeni događaje koje možete izmijeniti na tabletu, uključujući i one koji se odnose na prijatelje ili saradnike. Ovim se aplikaciji može omogućiti da šalje poruke koje izgledaju kao da dolaze od vlasnika kalendara, ili da mijenja događaje bez znanja vlasnika."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Dozvoljava aplikaciji dodavanje, uklanjanje i promjenu događaja koje možete mijenjati na TV-u, uključujući i one koji se odnose na prijatelje ili saradnike. Ovim se aplikaciji može omogućiti da šalje poruke koje izgledaju kao da dolaze od vlasnika kalendara ili da bez znanja vlasnika mijenjaju događaje."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Omogućava aplikaciji da doda, ukloni i promijeni događaje koje možete izmijeniti na telefonu, uključujući i one koji se odnose na prijatelje ili saradnike. Ovim se aplikaciji može omogućiti da šalje poruke koje izgledaju kao da dolaze od vlasnika kalendara, ili da mijenja događaje bez znanja vlasnika."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"pristup dodatnim informacijama o lokaciji"</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Dozvoljava aplikaciji pristup dodatnim naredbama pružatelja lokacija. Ovim se aplikaciji može dozvoliti da ometa rad GPS-a ili drugih izvora lokacija."</string>
+    <string name="permlab_accessFineLocation" msgid="251034415460950944">"pristup preciznoj lokaciji (utvrđena preko mreže i GPS-a)"</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Omogućava aplikaciji da dobije vašu tačnu lokaciju pomoću Globalnog pozicionog sistema (GPS) ili mrežnih resursa za lociranje kao što su repetitori mobilne mreže i Wi-Fi. Ove usluge za određivanje lokacije moraju biti uključene i dostupne vašem uređaju da bi ih aplikacija koristila. Aplikacije ih mogu koristiti za određivanje vaše lokacije, a mogu uzrokovati i dodatno trošenje baterije."</string>
+    <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"pristup približnoj lokaciji (utvrđena preko mreže)"</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Omogućava aplikaciji da dobije vašu približnu lokaciju. Ta lokacija je izvedena pomoću servisa za lociranje koji koriste mrežne resurse za lociranje kao što su repetitori mobilne mreže i Wi-Fi. Ove usluge za određivanje lokacije moraju biti uključene i dostupne vašem uređaju da bi ih aplikacija koristila. Aplikacije ih mogu koristiti za određivanje vaše približne lokacije."</string>
+    <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"izmjene postavki zvuka"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Omogućava aplikaciji izmjenu općih postavki zvuka, kao što su jačina zvuka i izbor izlaznog zvučnika."</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"snimanje audiozapisa"</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Omogućava aplikaciji snimanje zvuka s mikrofona. Ova dozvola omogućava aplikaciji snimanje zvučnog zapisa u bilo kom trenutku bez vaše potvrde."</string>
+    <string name="permlab_sim_communication" msgid="2935852302216852065">"slanje komandi SIM kartici"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Omogućava aplikaciji slanje naredbi na SIM. Ovo je vrlo opasno."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"snimanje slika i videozapisa"</string>
+    <string name="permdesc_camera" msgid="8497216524735535009">"Omogućava aplikaciji snimanje fotografija i videozapisa kamerom. Ova dozvola omogućava aplikaciji da bilo kada koristi kameru bez vašeg znanja."</string>
+    <string name="permlab_vibrate" msgid="7696427026057705834">"kontrola vibriranja"</string>
+    <string name="permdesc_vibrate" msgid="6284989245902300945">"Dozvoljava aplikaciji upravljanje vibracijom."</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"izravno zvanje telefonskih brojeva"</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Omogućava aplikaciji pozivanje telefonskih brojeva bez vašeg angažiranja. Ovo može uzrokovati neočekivane troškove ili pozive. Imajte na umu da ovo ne daje aplikaciji mogućnost pozivanja brojeva za hitne slučajeve. Zlonamjerne aplikacije vam mogu napraviti neočekivane troškove kroz vršenje poziva bez vašeg znanja."</string>
+    <string name="permlab_accessImsCallService" msgid="3574943847181793918">"pristup usluzi IMS pozivanja"</string>
+    <string name="permdesc_accessImsCallService" msgid="8992884015198298775">"Omogućava aplikaciji da koristi IMS uslugu za pozivanje bez vaše intervencije."</string>
+    <string name="permlab_readPhoneState" msgid="9178228524507610486">"čitanje statusa i identiteta telefona"</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Omogućava aplikaciji pristup telefonskim funkcijama uređaja. Ova dozvola omogućava aplikaciji određivanje telefonskog i identifikacionog broja uređaja, bez obzira da li je poziv aktivan i da li je uspostavljena veza sa pozivanim brojem."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"sprečavanje tableta da uđe u režim mirovanja"</string>
+    <string name="permlab_wakeLock" product="tv" msgid="2601193288949154131">"spriječi ulazak TV-a u režim mirovanja"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"sprečavanje telefona da uđe u režim mirovanja"</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Dozvoljava aplikaciji da spriječi tablet da ode u stanje mirovanja."</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="3208534859208996974">"Dozvoljava aplikaciji da spriječi ulazak TV-a u režim mirovanja."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="8559100677372928754">"Dozvoljava aplikaciji da spriječi telefon da ode u stanje mirovanja."</string>
+    <string name="permlab_transmitIr" msgid="7545858504238530105">"prijenos putem infracrvenog odašiljača"</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5358308854306529170">"Omogućava aplikaciji korištenje infracrvenog odašiljača tableta."</string>
+    <string name="permdesc_transmitIr" product="tv" msgid="3926790828514867101">"Dozvoljava aplikaciji korištenje infracrvenog predajnika na TV-u."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="7957763745020300725">"Omogućava aplikaciji korištenje infracrvenog odašiljača telefona."</string>
+    <string name="permlab_setWallpaper" msgid="6627192333373465143">"postavljanje pozadinske slike"</string>
+    <string name="permdesc_setWallpaper" msgid="7373447920977624745">"Dozvoljava aplikaciji postavljanje sistemske pozadine ekrana."</string>
+    <string name="permlab_setWallpaperHints" msgid="3278608165977736538">"prilagođavanje veličine pozadine"</string>
+    <string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Dozvoljava aplikaciji određivanje veličine sistemske pozadine ekrana."</string>
+    <string name="permlab_setTimeZone" msgid="2945079801013077340">"postavljanje vremenske zone"</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1676983712315827645">"Dozvoljava aplikaciji promjenu vremenske zone tableta."</string>
+    <string name="permdesc_setTimeZone" product="tv" msgid="888864653946175955">"Dozvoljava aplikaciji promjenu vremenske zone na TV-u."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4499943488436633398">"Dozvoljava aplikaciji promjenu vremenske zone telefona."</string>
+    <string name="permlab_getAccounts" msgid="1086795467760122114">"pronalaženje računa na uređaju"</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Omogućava aplikaciji dobijanje spiska računa koje tablet prepoznaje. Spisak može uključivati sve račune koje su kreirale instalirane aplikacije."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="4190633395633907543">"Dozvoljava aplikaciji da preuzme spisak računa koje TV prepoznaje. To može obuhvatiti sve račune koji su napravljeni pomoću aplikacija koje ste instalirali."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Omogućava aplikaciji dobijanje spiska računa koje telefon prepoznaje. Spisak može uključivati sve račune koje su kreirale instalirane aplikacije."</string>
+    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"prikaz mrežnih veza"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Omogućava aplikaciji pregled informacija o mrežnim vezama, npr. koje mreže postoje i koje su povezane."</string>
+    <string name="permlab_createNetworkSockets" msgid="7934516631384168107">"ima potpuni pristup mreži"</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Omogućava aplikaciji kreiranje spojnih tačaka sa mrežom i korištenje prilagođenih mrežnih protokola. Preglednik i druge aplikacije omogućavaju slanje podataka na internet, tako da ova dozvola nije potrebna za vršenje te radnje."</string>
+    <string name="permlab_changeNetworkState" msgid="958884291454327309">"izmjene povezivanja na mrežu"</string>
+    <string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Dozvoljava aplikaciji izmjenu stanja mrežne povezanosti."</string>
+    <string name="permlab_changeTetherState" msgid="5952584964373017960">"izmjene podijeljenog povezivanja"</string>
+    <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Dozvoljava aplikaciji izmjenu stanja povezanosti na podijeljenu mrežu."</string>
+    <string name="permlab_accessWifiState" msgid="5202012949247040011">"pregled Wi-Fi veza"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Omogućava aplikaciji pregled informacija o Wi-Fi mrežama, npr. da li je Wi-Fi omogućen i naziv povezanih Wi-Fi uređaja."</string>
+    <string name="permlab_changeWifiState" msgid="6550641188749128035">"uspostavljanje i prekidanje Wi-Fi veze"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Omogućava aplikaciji uspostavljanje i prekidanje veze sa Wi-Fi pristupnim tačkama, kao i promjenu konfiguracije uređaja za Wi-Fi mreže."</string>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"dozvoljava prijem paketa kroz Wi-Fi Multicast"</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na Wi-Fi mreži pomoću multicast tehnologije, a ne samo na vaš tablet. Troši više energije nego rad van multicast načina rada."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na Wi-Fi mreži pomoću multicast tehnologije, a ne samo na vaš TV. Troši više energije nego rad van multicast načina rada."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Omogućava aplikaciji prijem paketa poslanih svim uređajima na Wi-Fi mreži pomoću multicast tehnologije, a ne samo na vaš telefon. Troši više energije nego rad van multicast načina rada."</string>
+    <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"pristup Bluetooth postavkama"</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Dozvoljava aplikaciji konfiguriranje lokalnog Bluetooth tableta te otkrivanje udaljenih uređaja i sparivanje s njima."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Dozvoljava aplikaciji konfiguriranje lokalnog Bluetooth TV-a te otkrivanje i povezivanje s udaljenim uređajima."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Dozvoljava aplikaciji konfiguriranje lokalnog Bluetooth telefona te otkrivanje udaljenih uređaja i sparivanje s njima."</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"uspostavljanje i prekidanje veze sa WiMAX mrežama"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Dozvoljava aplikaciji da utvrdi da li je WiMAX omogućen i informacije o bilo kojoj WiMAX mreži koja je povezana."</string>
+    <string name="permlab_changeWimaxState" msgid="340465839241528618">"izmjene stanja WiMAX signala"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Omogućava aplikaciji uspostavljanje i prekidanje veze tableta sa WiMAX mrežama."</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Dozvoljava aplikaciji da TV poveže na WiMAX mreže ili da ga isključi s njih."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Omogućava aplikaciji uspostavljanje i prekidanje veze telefona sa WiMAX mrežama."</string>
+    <string name="permlab_bluetooth" msgid="6127769336339276828">"uparivanje sa Bluetooth uređajima"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Omogućava aplikaciji prikaz konfiguracije za Bluetooth na tabletu, kao i uspostavljanje i prihvatanje veza sa uparenim uređajima."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Dozvoljava aplikaciji prikaz konfiguracije Bluetooth veze na TV-u te uspostavljanje i prihvatanje veza s ravnopravnim uređajima."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Omogućava aplikaciji prikaz konfiguracije za Bluetooth na telefonu, kao i uspostavljanje i prihvatanje veza sa uparenim uređajima."</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"upravljanje NFC-om"</string>
+    <string name="permdesc_nfc" msgid="7120611819401789907">"Dozvoljava aplikaciji komuniciranje sa NFC (komunikacija bliskog polja) oznakama, karticama i čitačima."</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivacija zaključavanja ekrana"</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Omogućava aplikaciji deaktivaciju zaključane tastature i svih povezanih zaštita. Naprimjer, telefon deaktivira zaključavanje tastature kod dolaznog telefonskog poziva, a zatim ponovo aktivira zaključavanje tastature kada je poziv završen."</string>
+    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljanje hardverom za otiske prstiju"</string>
+    <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Omogućava aplikaciji da koristi metode za dodavanje i brisanje šablona otisaka prstiju za upotrebu."</string>
+    <string name="permlab_useFingerprint" msgid="3150478619915124905">"korištenje hardvera za otiske prstiju"</string>
+    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Omogućava aplikaciji da za provjeru vjerodostojnosti koristi hardver za otiske prstiju"</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Otkriven je djelomičan otisak prsta. Pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nije uspjela obrada otiska prsta. Pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Senzor za otisak prsta je prljav. Očistite ga i pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Prst je uklonjen prebrzo. Pokušajte ponovo."</string>
+    <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Prst je uklonjen presporo. Pokušajte ponovo."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_hw_not_available (7955921658939936596) -->
-    <skip />
-    <!-- no translation found for fingerprint_error_no_space (1055819001126053318) -->
-    <skip />
-    <!-- no translation found for fingerprint_error_timeout (3927186043737732875) -->
-    <skip />
-    <!-- no translation found for fingerprint_error_canceled (4402024612660774395) -->
-    <skip />
-    <!-- no translation found for fingerprint_error_lockout (5536934748136933450) -->
-    <skip />
-    <!-- no translation found for fingerprint_error_unable_to_process (6107816084103552441) -->
-    <skip />
-    <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
-    <skip />
+    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Hardver za otisak prsta nije dostupan."</string>
+    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Otisak prsta se ne može sačuvati. Uklonite postojeći otisak prsta."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Vremensko ograničenje za otisak prsta je isteklo. Pokušajte ponovo."</string>
+    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja sa otiskom prsta je otkazana."</string>
+    <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
+    <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
+    <string name="fingerprint_name_template" msgid="5870957565512716938">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_icon_content_description (2340202869968465936) -->
-    <skip />
-    <!-- no translation found for permlab_readSyncSettings (6201810008230503052) -->
-    <skip />
-    <!-- no translation found for permdesc_readSyncSettings (2706745674569678644) -->
-    <skip />
-    <!-- no translation found for permlab_writeSyncSettings (5408694875793945314) -->
-    <skip />
-    <!-- no translation found for permdesc_writeSyncSettings (8956262591306369868) -->
-    <skip />
-    <!-- no translation found for permlab_readSyncStats (7396577451360202448) -->
-    <skip />
-    <!-- no translation found for permdesc_readSyncStats (1510143761757606156) -->
-    <skip />
-    <!-- no translation found for permlab_sdcardRead (367275095159405468) -->
-    <skip />
-    <!-- no translation found for permlab_sdcardRead (2188156462934977940) -->
-    <skip />
-    <!-- no translation found for permdesc_sdcardRead (3446988712598386079) -->
-    <skip />
-    <!-- no translation found for permdesc_sdcardRead (2607362473654975411) -->
-    <skip />
-    <!-- no translation found for permlab_sdcardWrite (8485979062254666748) -->
-    <skip />
-    <!-- no translation found for permlab_sdcardWrite (8805693630050458763) -->
-    <skip />
-    <!-- no translation found for permdesc_sdcardWrite (6175406299445710888) -->
-    <skip />
-    <!-- no translation found for permdesc_sdcardWrite (4337417790936632090) -->
-    <skip />
-    <!-- no translation found for permlab_use_sip (2052499390128979920) -->
-    <skip />
-    <!-- no translation found for permdesc_use_sip (2297804849860225257) -->
-    <skip />
-    <!-- no translation found for permlab_register_sim_subscription (3166535485877549177) -->
-    <skip />
-    <!-- no translation found for permdesc_register_sim_subscription (2138909035926222911) -->
-    <skip />
-    <!-- no translation found for permlab_register_call_provider (108102120289029841) -->
-    <skip />
-    <!-- no translation found for permdesc_register_call_provider (7034310263521081388) -->
-    <skip />
-    <!-- no translation found for permlab_connection_manager (1116193254522105375) -->
-    <skip />
-    <!-- no translation found for permdesc_connection_manager (5925480810356483565) -->
-    <skip />
-    <!-- no translation found for permlab_bind_incall_service (6773648341975287125) -->
-    <skip />
-    <!-- no translation found for permdesc_bind_incall_service (8343471381323215005) -->
-    <skip />
-    <!-- no translation found for permlab_bind_connection_service (3557341439297014940) -->
-    <skip />
-    <!-- no translation found for permdesc_bind_connection_service (4008754499822478114) -->
-    <skip />
-    <!-- no translation found for permlab_control_incall_experience (9061024437607777619) -->
-    <skip />
-    <!-- no translation found for permdesc_control_incall_experience (915159066039828124) -->
-    <skip />
-    <!-- no translation found for permlab_readNetworkUsageHistory (7862593283611493232) -->
-    <skip />
-    <!-- no translation found for permdesc_readNetworkUsageHistory (7689060749819126472) -->
-    <skip />
-    <!-- no translation found for permlab_manageNetworkPolicy (2562053592339859990) -->
-    <skip />
-    <!-- no translation found for permdesc_manageNetworkPolicy (7537586771559370668) -->
-    <skip />
-    <!-- no translation found for permlab_modifyNetworkAccounting (5088217309088729650) -->
-    <skip />
-    <!-- no translation found for permdesc_modifyNetworkAccounting (5443412866746198123) -->
-    <skip />
-    <!-- no translation found for permlab_accessNotifications (7673416487873432268) -->
-    <skip />
-    <!-- no translation found for permdesc_accessNotifications (458457742683431387) -->
-    <skip />
-    <!-- no translation found for permlab_bindNotificationListenerService (7057764742211656654) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNotificationListenerService (985697918576902986) -->
-    <skip />
-    <!-- no translation found for permlab_bindConditionProviderService (1180107672332704641) -->
-    <skip />
-    <!-- no translation found for permdesc_bindConditionProviderService (1680513931165058425) -->
-    <skip />
-    <!-- no translation found for permlab_bindDreamService (4153646965978563462) -->
-    <skip />
-    <!-- no translation found for permdesc_bindDreamService (7325825272223347863) -->
-    <skip />
-    <!-- no translation found for permlab_invokeCarrierSetup (3699600833975117478) -->
-    <skip />
-    <!-- no translation found for permdesc_invokeCarrierSetup (4159549152529111920) -->
-    <skip />
-    <!-- no translation found for permlab_accessNetworkConditions (8206077447838909516) -->
-    <skip />
-    <!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
-    <skip />
-    <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
-    <skip />
-    <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
-    <skip />
-    <!-- no translation found for permlab_accessDrmCertificates (7436886640723203615) -->
-    <skip />
-    <!-- no translation found for permdesc_accessDrmCertificates (8073288354426159089) -->
-    <skip />
-    <!-- no translation found for permlab_handoverStatus (7820353257219300883) -->
-    <skip />
-    <!-- no translation found for permdesc_handoverStatus (4788144087245714948) -->
-    <skip />
-    <!-- no translation found for permlab_removeDrmCertificates (7044888287209892751) -->
-    <skip />
-    <!-- no translation found for permdesc_removeDrmCertificates (7272999075113400993) -->
-    <skip />
-    <!-- no translation found for permlab_bindCarrierMessagingService (1490229371796969158) -->
-    <skip />
-    <!-- no translation found for permdesc_bindCarrierMessagingService (2762882888502113944) -->
-    <skip />
-    <!-- no translation found for permlab_bindCarrierServices (3233108656245526783) -->
-    <skip />
-    <!-- no translation found for permdesc_bindCarrierServices (1391552602551084192) -->
-    <skip />
-    <!-- no translation found for permlab_access_notification_policy (4247510821662059671) -->
-    <skip />
-    <!-- no translation found for permdesc_access_notification_policy (3296832375218749580) -->
-    <skip />
-    <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
-    <skip />
-    <!-- no translation found for policydesc_limitPassword (2502021457917874968) -->
-    <skip />
-    <!-- no translation found for policylab_watchLogin (914130646942199503) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin (3215729294215070072) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin (2707817988309890256) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin (5712323091846761073) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin_secondaryUser (4280246270601044505) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin_secondaryUser (3484832653564483250) -->
-    <skip />
-    <!-- no translation found for policydesc_watchLogin_secondaryUser (2185480427217127147) -->
-    <skip />
-    <!-- no translation found for policylab_resetPassword (4934707632423915395) -->
-    <skip />
-    <!-- no translation found for policydesc_resetPassword (1278323891710619128) -->
-    <skip />
-    <!-- no translation found for policylab_forceLock (2274085384704248431) -->
-    <skip />
-    <!-- no translation found for policydesc_forceLock (1141797588403827138) -->
-    <skip />
-    <!-- no translation found for policylab_wipeData (3910545446758639713) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData (4306184096067756876) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData (5816221315214527028) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData (5096895604574188391) -->
-    <skip />
-    <!-- no translation found for policylab_wipeData_secondaryUser (8362863289455531813) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData_secondaryUser (6336255514635308054) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData_secondaryUser (2086473496848351810) -->
-    <skip />
-    <!-- no translation found for policydesc_wipeData_secondaryUser (6787904546711590238) -->
-    <skip />
-    <!-- no translation found for policylab_setGlobalProxy (2784828293747791446) -->
-    <skip />
-    <!-- no translation found for policydesc_setGlobalProxy (8459859731153370499) -->
-    <skip />
-    <!-- no translation found for policylab_expirePassword (5610055012328825874) -->
-    <skip />
-    <!-- no translation found for policydesc_expirePassword (5367525762204416046) -->
-    <skip />
-    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
-    <skip />
-    <!-- no translation found for policydesc_encryptedStorage (2637732115325316992) -->
-    <skip />
-    <!-- no translation found for policylab_disableCamera (6395301023152297826) -->
-    <skip />
-    <!-- no translation found for policydesc_disableCamera (2306349042834754597) -->
-    <skip />
-    <!-- no translation found for policylab_disableKeyguardFeatures (8552277871075367771) -->
-    <skip />
-    <!-- no translation found for policydesc_disableKeyguardFeatures (2044755691354158439) -->
-    <skip />
-    <!-- no translation found for phoneTypes:0 (8901098336658710359) -->
-    <!-- no translation found for phoneTypes:1 (869923650527136615) -->
-    <!-- no translation found for phoneTypes:2 (7897544654242874543) -->
-    <!-- no translation found for phoneTypes:3 (1103601433382158155) -->
-    <!-- no translation found for phoneTypes:4 (1735177144948329370) -->
-    <!-- no translation found for phoneTypes:5 (603878674477207394) -->
-    <!-- no translation found for phoneTypes:6 (1650824275177931637) -->
-    <!-- no translation found for phoneTypes:7 (9192514806975898961) -->
-    <!-- no translation found for emailAddressTypes:0 (8073994352956129127) -->
-    <!-- no translation found for emailAddressTypes:1 (7084237356602625604) -->
-    <!-- no translation found for emailAddressTypes:2 (1112044410659011023) -->
-    <!-- no translation found for emailAddressTypes:3 (2374913952870110618) -->
-    <!-- no translation found for postalAddressTypes:0 (6880257626740047286) -->
-    <!-- no translation found for postalAddressTypes:1 (5629153956045109251) -->
-    <!-- no translation found for postalAddressTypes:2 (4966604264500343469) -->
-    <!-- no translation found for postalAddressTypes:3 (4932682847595299369) -->
-    <!-- no translation found for imAddressTypes:0 (1738585194601476694) -->
-    <!-- no translation found for imAddressTypes:1 (1359644565647383708) -->
-    <!-- no translation found for imAddressTypes:2 (7868549401053615677) -->
-    <!-- no translation found for imAddressTypes:3 (3145118944639869809) -->
-    <!-- no translation found for organizationTypes:0 (7546335612189115615) -->
-    <!-- no translation found for organizationTypes:1 (4378074129049520373) -->
-    <!-- no translation found for organizationTypes:2 (3455047468583965104) -->
-    <!-- no translation found for imProtocols:0 (8595261363518459565) -->
-    <!-- no translation found for imProtocols:1 (7390473628275490700) -->
-    <!-- no translation found for imProtocols:2 (7882877134931458217) -->
-    <!-- no translation found for imProtocols:3 (5035376313200585242) -->
-    <!-- no translation found for imProtocols:4 (7532363178459444943) -->
-    <!-- no translation found for imProtocols:5 (3713441034299660749) -->
-    <!-- no translation found for imProtocols:6 (2506857312718630823) -->
-    <!-- no translation found for imProtocols:7 (1648797903785279353) -->
-    <!-- no translation found for phoneTypeCustom (1644738059053355820) -->
-    <skip />
-    <!-- no translation found for phoneTypeHome (2570923463033985887) -->
-    <skip />
-    <!-- no translation found for phoneTypeMobile (6501463557754751037) -->
-    <skip />
-    <!-- no translation found for phoneTypeWork (8863939667059911633) -->
-    <skip />
-    <!-- no translation found for phoneTypeFaxWork (3517792160008890912) -->
-    <skip />
-    <!-- no translation found for phoneTypeFaxHome (2067265972322971467) -->
-    <skip />
-    <!-- no translation found for phoneTypePager (7582359955394921732) -->
-    <skip />
-    <!-- no translation found for phoneTypeOther (1544425847868765990) -->
-    <skip />
-    <!-- no translation found for phoneTypeCallback (2712175203065678206) -->
-    <skip />
-    <!-- no translation found for phoneTypeCar (8738360689616716982) -->
-    <skip />
-    <!-- no translation found for phoneTypeCompanyMain (540434356461478916) -->
-    <skip />
-    <!-- no translation found for phoneTypeIsdn (8022453193171370337) -->
-    <skip />
-    <!-- no translation found for phoneTypeMain (6766137010628326916) -->
-    <skip />
-    <!-- no translation found for phoneTypeOtherFax (8587657145072446565) -->
-    <skip />
-    <!-- no translation found for phoneTypeRadio (4093738079908667513) -->
-    <skip />
-    <!-- no translation found for phoneTypeTelex (3367879952476250512) -->
-    <skip />
-    <!-- no translation found for phoneTypeTtyTdd (8606514378585000044) -->
-    <skip />
-    <!-- no translation found for phoneTypeWorkMobile (1311426989184065709) -->
-    <skip />
-    <!-- no translation found for phoneTypeWorkPager (649938731231157056) -->
-    <skip />
-    <!-- no translation found for phoneTypeAssistant (5596772636128562884) -->
-    <skip />
-    <!-- no translation found for phoneTypeMms (7254492275502768992) -->
-    <skip />
-    <!-- no translation found for eventTypeCustom (7837586198458073404) -->
-    <skip />
-    <!-- no translation found for eventTypeBirthday (2813379844211390740) -->
-    <skip />
-    <!-- no translation found for eventTypeAnniversary (3876779744518284000) -->
-    <skip />
-    <!-- no translation found for eventTypeOther (7388178939010143077) -->
-    <skip />
-    <!-- no translation found for emailTypeCustom (8525960257804213846) -->
-    <skip />
-    <!-- no translation found for emailTypeHome (449227236140433919) -->
-    <skip />
-    <!-- no translation found for emailTypeWork (3548058059601149973) -->
-    <skip />
-    <!-- no translation found for emailTypeOther (2923008695272639549) -->
-    <skip />
-    <!-- no translation found for emailTypeMobile (119919005321166205) -->
-    <skip />
-    <!-- no translation found for postalTypeCustom (8903206903060479902) -->
-    <skip />
-    <!-- no translation found for postalTypeHome (8165756977184483097) -->
-    <skip />
-    <!-- no translation found for postalTypeWork (5268172772387694495) -->
-    <skip />
-    <!-- no translation found for postalTypeOther (2726111966623584341) -->
-    <skip />
-    <!-- no translation found for imTypeCustom (2074028755527826046) -->
-    <skip />
-    <!-- no translation found for imTypeHome (6241181032954263892) -->
-    <skip />
-    <!-- no translation found for imTypeWork (1371489290242433090) -->
-    <skip />
-    <!-- no translation found for imTypeOther (5377007495735915478) -->
-    <skip />
-    <!-- no translation found for imProtocolCustom (6919453836618749992) -->
-    <skip />
-    <!-- no translation found for imProtocolAim (7050360612368383417) -->
-    <skip />
-    <!-- no translation found for imProtocolMsn (144556545420769442) -->
-    <skip />
-    <!-- no translation found for imProtocolYahoo (8271439408469021273) -->
-    <skip />
-    <!-- no translation found for imProtocolSkype (9019296744622832951) -->
-    <skip />
-    <!-- no translation found for imProtocolQq (8887484379494111884) -->
-    <skip />
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
-    <!-- no translation found for imProtocolIcq (1574870433606517315) -->
-    <skip />
-    <!-- no translation found for imProtocolJabber (2279917630875771722) -->
-    <skip />
-    <!-- no translation found for imProtocolNetMeeting (8287625655986827971) -->
-    <skip />
-    <!-- no translation found for orgTypeWork (29268870505363872) -->
-    <skip />
-    <!-- no translation found for orgTypeOther (3951781131570124082) -->
-    <skip />
-    <!-- no translation found for orgTypeCustom (225523415372088322) -->
-    <skip />
-    <!-- no translation found for relationTypeCustom (3542403679827297300) -->
-    <skip />
-    <!-- no translation found for relationTypeAssistant (6274334825195379076) -->
-    <skip />
-    <!-- no translation found for relationTypeBrother (8757913506784067713) -->
-    <skip />
-    <!-- no translation found for relationTypeChild (1890746277276881626) -->
-    <skip />
-    <!-- no translation found for relationTypeDomesticPartner (6904807112121122133) -->
-    <skip />
-    <!-- no translation found for relationTypeFather (5228034687082050725) -->
-    <skip />
-    <!-- no translation found for relationTypeFriend (7313106762483391262) -->
-    <skip />
-    <!-- no translation found for relationTypeManager (6365677861610137895) -->
-    <skip />
-    <!-- no translation found for relationTypeMother (4578571352962758304) -->
-    <skip />
-    <!-- no translation found for relationTypeParent (4755635567562925226) -->
-    <skip />
-    <!-- no translation found for relationTypePartner (7266490285120262781) -->
-    <skip />
-    <!-- no translation found for relationTypeReferredBy (101573059844135524) -->
-    <skip />
-    <!-- no translation found for relationTypeRelative (1799819930085610271) -->
-    <skip />
-    <!-- no translation found for relationTypeSister (1735983554479076481) -->
-    <skip />
-    <!-- no translation found for relationTypeSpouse (394136939428698117) -->
-    <skip />
-    <!-- no translation found for sipAddressTypeCustom (2473580593111590945) -->
-    <skip />
-    <!-- no translation found for sipAddressTypeHome (6093598181069359295) -->
-    <skip />
-    <!-- no translation found for sipAddressTypeWork (6920725730797099047) -->
-    <skip />
-    <!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
-    <skip />
-    <!-- no translation found for quick_contacts_not_available (746098007828579688) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_pin_prompt (8027680321614196258) -->
-    <skip />
-    <!-- no translation found for keyguard_password_entry_touch_hint (7858547464982981384) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_password_code (1054721668279049780) -->
-    <skip />
-    <!-- no translation found for keyguard_password_enter_pin_password_code (6391755146112503443) -->
-    <skip />
-    <!-- no translation found for keyguard_password_wrong_pin_code (2422225591006134936) -->
-    <skip />
-    <!-- no translation found for keyguard_label_text (861796461028298424) -->
-    <skip />
-    <!-- no translation found for emergency_call_dialog_number_for_display (696192103195090970) -->
-    <skip />
-    <!-- no translation found for lockscreen_carrier_default (6169005837238288522) -->
-    <skip />
-    <!-- no translation found for lockscreen_screen_locked (7288443074806832904) -->
-    <skip />
-    <!-- no translation found for lockscreen_instructions_when_pattern_enabled (46154051614126049) -->
-    <skip />
-    <!-- no translation found for lockscreen_instructions_when_pattern_disabled (686260028797158364) -->
-    <skip />
-    <!-- no translation found for lockscreen_pattern_instructions (7478703254964810302) -->
-    <skip />
-    <!-- no translation found for lockscreen_emergency_call (5298642613417801888) -->
-    <skip />
-    <!-- no translation found for lockscreen_return_to_call (5244259785500040021) -->
-    <skip />
-    <!-- no translation found for lockscreen_pattern_correct (9039008650362261237) -->
-    <skip />
-    <!-- no translation found for lockscreen_pattern_wrong (4317955014948108794) -->
-    <skip />
-    <!-- no translation found for lockscreen_password_wrong (5737815393253165301) -->
-    <skip />
-    <!-- no translation found for faceunlock_multiple_failures (754137583022792429) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_message_short (5099439277819215399) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_message (151659196095791474) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_message (1943633865476989599) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_message (2186920585695169078) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_instructions (5372787138023272615) -->
-    <skip />
-    <!-- no translation found for lockscreen_missing_sim_instructions_long (3526573099019319472) -->
-    <skip />
-    <!-- no translation found for lockscreen_permanent_disabled_sim_message_short (5096149665138916184) -->
-    <skip />
-    <!-- no translation found for lockscreen_permanent_disabled_sim_instructions (910904643433151371) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_prev_description (6300840251218161534) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_next_description (573285210424377338) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_pause_description (3980308465056173363) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_play_description (1901258823643886401) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_stop_description (5907083260651210034) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_rew_description (6944412838651990410) -->
-    <skip />
-    <!-- no translation found for lockscreen_transport_ffw_description (42987149870928985) -->
-    <skip />
-    <!-- no translation found for emergency_calls_only (6733978304386365407) -->
-    <!-- no translation found for emergency_calls_only (2485604591272668370) -->
-    <skip />
-    <!-- no translation found for lockscreen_network_locked_message (143389224986028501) -->
-    <skip />
-    <!-- no translation found for lockscreen_sim_puk_locked_message (7441797339976230) -->
-    <skip />
-    <!-- no translation found for lockscreen_sim_puk_locked_instructions (8127916255245181063) -->
-    <skip />
-    <!-- no translation found for lockscreen_sim_locked_message (8066660129206001039) -->
-    <skip />
-    <!-- no translation found for lockscreen_sim_unlock_progress_dialog_message (595323214052881264) -->
-    <skip />
-    <!-- no translation found for lockscreen_too_many_failed_attempts_dialog_message (6481623830344107222) -->
-    <skip />
-    <!-- no translation found for lockscreen_too_many_failed_password_attempts_dialog_message (2725973286239344555) -->
-    <skip />
-    <!-- no translation found for lockscreen_too_many_failed_pin_attempts_dialog_message (6216672706545696955) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_glogin (9191611984625460820) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_glogin (5316664559603394684) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_glogin (2590227559763762751) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_at_wipe (6128106399745755604) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_at_wipe (950408382418270260) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_almost_at_wipe (8603565142156826565) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_now_wiping (280873516493934365) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_now_wiping (3195755534096192191) -->
-    <skip />
-    <!-- no translation found for lockscreen_failed_attempts_now_wiping (3025504721764922246) -->
-    <skip />
-    <!-- no translation found for lockscreen_too_many_failed_attempts_countdown (6251480343394389665) -->
-    <skip />
-    <!-- no translation found for lockscreen_forgot_pattern_button_text (2626999449610695930) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_forgot_pattern (2588521501166032747) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_too_many_attempts (2751368605287288808) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_instructions (3931816256100707784) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_username_hint (8846881424106484447) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_password_hint (5958028383954738528) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_submit_button (7130893694795786300) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_invalid_input (1364051473347485908) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_account_recovery_hint (1696924763690379073) -->
-    <skip />
-    <!-- no translation found for lockscreen_glogin_checking_password (7114627351286933867) -->
-    <skip />
-    <!-- no translation found for lockscreen_unlock_label (737440483220667054) -->
-    <skip />
-    <!-- no translation found for lockscreen_sound_on_label (9068877576513425970) -->
-    <skip />
-    <!-- no translation found for lockscreen_sound_off_label (996822825154319026) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_start (3941045502933142847) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_cleared (5583479721001639579) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_cell_added (6756031208359292487) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_cell_added_verbose (7264580781744026939) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_detected (4988730895554057058) -->
-    <skip />
-    <!-- no translation found for lockscreen_access_pattern_area (400813207572953209) -->
-    <!-- no translation found for lockscreen_access_pattern_area () -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_add_widget (8273277058724924654) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget_empty_slot (1281505703307930757) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_unlock_area_expanded (2278106022311170299) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_unlock_area_collapsed (6366992066936076396) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget (6527131039741808240) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_user_selector (1226798370913698896) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_status (8008264603935930611) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_camera (8904231194181114603) -->
-    <skip />
-    <!-- no translation found for keygaurd_accessibility_media_controls (262209654292161806) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget_reorder_start (8736853615588828197) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget_reorder_end (7170190950870468320) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_widget_deleted (4426204263929224434) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_expand_lock_area (519859720934178024) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_slide_unlock (2959928478764697254) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_pattern_unlock (1490840706075246612) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_face_unlock (4817282543351718535) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_pin_unlock (2469687111784035046) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_password_unlock (7675777623912155089) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_pattern_area (7679891324509597904) -->
-    <skip />
-    <!-- no translation found for keyguard_accessibility_slide_area (6736064494019979544) -->
-    <skip />
-    <!-- no translation found for password_keyboard_label_symbol_key (992280756256536042) -->
-    <skip />
-    <!-- no translation found for password_keyboard_label_alpha_key (8001096175167485649) -->
-    <skip />
-    <!-- no translation found for password_keyboard_label_alt_key (1284820942620288678) -->
-    <skip />
-    <!-- no translation found for granularity_label_character (7336470535385009523) -->
-    <skip />
-    <!-- no translation found for granularity_label_word (7075570328374918660) -->
-    <skip />
-    <!-- no translation found for granularity_label_link (5815508880782488267) -->
-    <skip />
-    <!-- no translation found for granularity_label_line (5764267235026120888) -->
-    <skip />
-    <!-- no translation found for factorytest_failed (5410270329114212041) -->
-    <skip />
-    <!-- no translation found for factorytest_not_system (4435201656767276723) -->
-    <skip />
-    <!-- no translation found for factorytest_no_action (872991874799998561) -->
-    <skip />
-    <!-- no translation found for factorytest_reboot (6320168203050791643) -->
-    <skip />
-    <!-- no translation found for js_dialog_title (1987483977834603872) -->
-    <skip />
-    <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
-    <skip />
-    <!-- no translation found for js_dialog_before_unload_title (2619376555525116593) -->
-    <skip />
-    <!-- no translation found for js_dialog_before_unload_positive_button (3112752010600484130) -->
-    <skip />
-    <!-- no translation found for js_dialog_before_unload_negative_button (5614861293026099715) -->
-    <skip />
-    <!-- no translation found for js_dialog_before_unload (3468816357095378590) -->
-    <skip />
-    <!-- no translation found for save_password_label (6860261758665825069) -->
-    <skip />
-    <!-- no translation found for double_tap_toast (4595046515400268881) -->
-    <skip />
-    <!-- no translation found for autofill_this_form (4616758841157816676) -->
-    <skip />
-    <!-- no translation found for setup_autofill (7103495070180590814) -->
-    <skip />
-    <!-- no translation found for autofill_address_name_separator (6350145154779706772) -->
-    <skip />
-    <!-- no translation found for autofill_address_summary_name_format (3268041054899214945) -->
-    <skip />
-    <!-- no translation found for autofill_address_summary_separator (7483307893170324129) -->
-    <skip />
-    <!-- no translation found for autofill_address_summary_format (4874459455786827344) -->
-    <skip />
-    <!-- no translation found for autofill_province (2231806553863422300) -->
-    <skip />
-    <!-- no translation found for autofill_postal_code (4696430407689377108) -->
-    <skip />
-    <!-- no translation found for autofill_state (6988894195520044613) -->
-    <skip />
-    <!-- no translation found for autofill_zip_code (8697544592627322946) -->
-    <skip />
-    <!-- no translation found for autofill_county (237073771020362891) -->
-    <skip />
-    <!-- no translation found for autofill_island (4020100875984667025) -->
-    <skip />
-    <!-- no translation found for autofill_district (8400735073392267672) -->
-    <skip />
-    <!-- no translation found for autofill_department (5343279462564453309) -->
-    <skip />
-    <!-- no translation found for autofill_prefecture (2028499485065800419) -->
-    <skip />
-    <!-- no translation found for autofill_parish (8202206105468820057) -->
-    <skip />
-    <!-- no translation found for autofill_area (3547409050889952423) -->
-    <skip />
-    <!-- no translation found for autofill_emirate (2893880978835698818) -->
-    <skip />
-    <!-- no translation found for permlab_readHistoryBookmarks (3775265775405106983) -->
-    <skip />
-    <!-- no translation found for permdesc_readHistoryBookmarks (8462378226600439658) -->
-    <skip />
-    <!-- no translation found for permlab_writeHistoryBookmarks (3714785165273314490) -->
-    <skip />
-    <!-- no translation found for permdesc_writeHistoryBookmarks (6825527469145760922) -->
-    <skip />
-    <!-- no translation found for permdesc_writeHistoryBookmarks (7007393823197766548) -->
-    <skip />
-    <!-- no translation found for permdesc_writeHistoryBookmarks (8497389531014185509) -->
-    <skip />
-    <!-- no translation found for permlab_setAlarm (1379294556362091814) -->
-    <skip />
-    <!-- no translation found for permdesc_setAlarm (316392039157473848) -->
-    <skip />
-    <!-- no translation found for permlab_addVoicemail (5525660026090959044) -->
-    <skip />
-    <!-- no translation found for permdesc_addVoicemail (6604508651428252437) -->
-    <skip />
-    <!-- no translation found for permlab_writeGeolocationPermissions (5962224158955273932) -->
-    <skip />
-    <!-- no translation found for permdesc_writeGeolocationPermissions (1083743234522638747) -->
-    <skip />
-    <!-- no translation found for save_password_message (767344687139195790) -->
-    <skip />
-    <!-- no translation found for save_password_notnow (6389675316706699758) -->
-    <skip />
-    <!-- no translation found for save_password_remember (6491879678996749466) -->
-    <skip />
-    <!-- no translation found for save_password_never (8274330296785855105) -->
-    <skip />
-    <!-- no translation found for open_permission_deny (7374036708316629800) -->
-    <skip />
-    <!-- no translation found for text_copied (4985729524670131385) -->
-    <skip />
-    <!-- no translation found for more_item_label (4650918923083320495) -->
-    <skip />
-    <!-- no translation found for prepend_shortcut_label (2572214461676015642) -->
-    <skip />
-    <!-- no translation found for menu_space_shortcut_label (2410328639272162537) -->
-    <skip />
-    <!-- no translation found for menu_enter_shortcut_label (2743362785111309668) -->
-    <skip />
-    <!-- no translation found for menu_delete_shortcut_label (3658178007202748164) -->
-    <skip />
-    <!-- no translation found for search_go (8298016669822141719) -->
-    <skip />
-    <!-- no translation found for search_hint (1733947260773056054) -->
-    <skip />
-    <!-- no translation found for searchview_description_search (6749826639098512120) -->
-    <skip />
-    <!-- no translation found for searchview_description_query (5911778593125355124) -->
-    <skip />
-    <!-- no translation found for searchview_description_clear (1330281990951833033) -->
-    <skip />
-    <!-- no translation found for searchview_description_submit (2688450133297983542) -->
-    <skip />
-    <!-- no translation found for searchview_description_voice (2453203695674994440) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
-    <skip />
-    <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
-    <skip />
-    <!-- no translation found for oneMonthDurationPast (7396384508953779925) -->
-    <skip />
-    <!-- no translation found for beforeOneMonthDurationPast (909134546836499826) -->
-    <skip />
-    <!-- no translation found for last_num_days (5104533550723932025) -->
-    <!-- no translation found for last_month (3959346739979055432) -->
-    <skip />
-    <!-- no translation found for older (5211975022815554840) -->
-    <skip />
-    <!-- no translation found for preposition_for_date (9093949757757445117) -->
-    <skip />
-    <!-- no translation found for preposition_for_time (5506831244263083793) -->
-    <skip />
-    <!-- no translation found for preposition_for_year (5040395640711867177) -->
-    <skip />
-    <!-- no translation found for day (8144195776058119424) -->
-    <skip />
-    <!-- no translation found for days (4774547661021344602) -->
-    <skip />
-    <!-- no translation found for hour (2126771916426189481) -->
-    <skip />
-    <!-- no translation found for hours (894424005266852993) -->
-    <skip />
-    <!-- no translation found for minute (9148878657703769868) -->
-    <skip />
-    <!-- no translation found for minutes (5646001005827034509) -->
-    <skip />
-    <!-- no translation found for second (3184235808021478) -->
-    <skip />
-    <!-- no translation found for seconds (3161515347216589235) -->
-    <skip />
-    <!-- no translation found for week (5617961537173061583) -->
-    <skip />
-    <!-- no translation found for weeks (6509623834583944518) -->
-    <skip />
-    <!-- no translation found for year (4001118221013892076) -->
-    <skip />
-    <!-- no translation found for years (6881577717993213522) -->
-    <skip />
-    <!-- no translation found for duration_seconds (4527986939729687805) -->
-    <!-- no translation found for duration_minutes (643786953939956125) -->
-    <!-- no translation found for duration_hours (6826233369186668274) -->
-    <!-- no translation found for VideoView_error_title (3534509135438353077) -->
-    <skip />
-    <!-- no translation found for VideoView_error_text_invalid_progressive_playback (3186670335938670444) -->
-    <skip />
-    <!-- no translation found for VideoView_error_text_unknown (3450439155187810085) -->
-    <skip />
-    <!-- no translation found for VideoView_error_button (2822238215100679592) -->
-    <skip />
-    <!-- no translation found for relative_time (1818557177829411417) -->
-    <skip />
-    <!-- no translation found for noon (7245353528818587908) -->
-    <skip />
-    <!-- no translation found for Noon (3342127745230013127) -->
-    <skip />
-    <!-- no translation found for midnight (7166259508850457595) -->
-    <skip />
-    <!-- no translation found for Midnight (5630806906897892201) -->
-    <skip />
-    <!-- no translation found for elapsed_time_short_format_mm_ss (4431555943828711473) -->
-    <skip />
-    <!-- no translation found for elapsed_time_short_format_h_mm_ss (1846071997616654124) -->
-    <skip />
-    <!-- no translation found for selectAll (6876518925844129331) -->
-    <skip />
-    <!-- no translation found for cut (3092569408438626261) -->
-    <skip />
-    <!-- no translation found for copy (2681946229533511987) -->
-    <skip />
-    <!-- no translation found for paste (5629880836805036433) -->
-    <skip />
-    <!-- no translation found for paste_as_plain_text (5427792741908010675) -->
-    <skip />
-    <!-- no translation found for replace (5781686059063148930) -->
-    <skip />
-    <!-- no translation found for delete (6098684844021697789) -->
-    <skip />
-    <!-- no translation found for copyUrl (2538211579596067402) -->
-    <skip />
-    <!-- no translation found for selectTextMode (1018691815143165326) -->
-    <skip />
-    <!-- no translation found for undo (7905788502491742328) -->
-    <skip />
-    <!-- no translation found for redo (7759464876566803888) -->
-    <skip />
-    <!-- no translation found for textSelectionCABTitle (5236850394370820357) -->
-    <skip />
-    <!-- no translation found for addToDictionary (4352161534510057874) -->
-    <skip />
-    <!-- no translation found for deleteText (6979668428458199034) -->
-    <skip />
-    <!-- no translation found for inputMethod (1653630062304567879) -->
-    <skip />
-    <!-- no translation found for editTextMenuTitle (4909135564941815494) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text_no_boot (6935190099204693424) -->
-    <skip />
-    <!-- no translation found for app_running_notification_title (8718335121060787914) -->
-    <skip />
-    <!-- no translation found for app_running_notification_text (4653586947747330058) -->
-    <skip />
-    <!-- no translation found for ok (5970060430562524910) -->
-    <skip />
-    <!-- no translation found for cancel (6442560571259935130) -->
-    <skip />
-    <!-- no translation found for yes (5362982303337969312) -->
-    <skip />
-    <!-- no translation found for no (5141531044935541497) -->
-    <skip />
-    <!-- no translation found for dialog_alert_title (2049658708609043103) -->
-    <skip />
-    <!-- no translation found for loading (7933681260296021180) -->
-    <skip />
-    <!-- no translation found for capital_on (1544682755514494298) -->
-    <skip />
-    <!-- no translation found for capital_off (6815870386972805832) -->
-    <skip />
-    <!-- no translation found for whichApplication (4533185947064773386) -->
-    <skip />
-    <!-- no translation found for whichApplicationNamed (8260158865936942783) -->
-    <skip />
-    <!-- no translation found for whichViewApplication (3272778576700572102) -->
-    <skip />
-    <!-- no translation found for whichViewApplicationNamed (2286418824011249620) -->
-    <skip />
-    <!-- no translation found for whichEditApplication (144727838241402655) -->
-    <skip />
-    <!-- no translation found for whichEditApplicationNamed (1775815530156447790) -->
-    <skip />
-    <!-- no translation found for whichSendApplication (6902512414057341668) -->
-    <skip />
-    <!-- no translation found for whichSendApplicationNamed (2799370240005424391) -->
-    <skip />
-    <!-- no translation found for whichHomeApplication (4307587691506919691) -->
-    <skip />
-    <!-- no translation found for whichHomeApplicationNamed (4493438593214760979) -->
-    <skip />
-    <!-- no translation found for alwaysUse (4583018368000610438) -->
-    <skip />
-    <!-- no translation found for use_a_different_app (8134926230585710243) -->
-    <skip />
-    <!-- no translation found for clearDefaultHintMsg (3252584689512077257) -->
-    <skip />
-    <!-- no translation found for chooseActivity (7486876147751803333) -->
-    <skip />
-    <!-- no translation found for chooseUsbActivity (6894748416073583509) -->
-    <skip />
-    <!-- no translation found for noApplications (2991814273936504689) -->
-    <skip />
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Ikona za otisak prsta"</string>
+    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čitanje postavki za sinhroniziranje"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Omogućava aplikaciji čitanje postavki sinhroniziranja za račun. Naprimjer, ovim se može utvrditi da li je aplikacija People sinhronizirana sa računom."</string>
+    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"uključivanje i isključivanje sinhroniziranja"</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Omogućava aplikaciji izmjenu postavki sinhroniziranja za račun. Naprimjer, ovim se može omogućiti sinhroniziranje aplikacije People sa računom."</string>
+    <string name="permlab_readSyncStats" msgid="7396577451360202448">"čitanje statistike sinhroniziranja"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Omogućava aplikaciji čitanje statistike sinhroniziranja za račun, uključujući historiju događaja sinhroniziranja i količinu sinhroniziranih podataka."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"čitanje sadržaja USB pohrane"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čitanje sadržaja SD kartice"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Omogućava aplikaciji čitanje sadržaja USB pohrane."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Omogućava aplikaciji čitanje sadržaja SD kartice."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"mijenjanje ili brisanje sadržaja USB pohrane"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"mijenjanje ili brisanje sadržaja SD kartice"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Dozvoljava pisanje na USB pohranu."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Dozvoljava aplikaciji pisanje na SD karticu."</string>
+    <string name="permlab_use_sip" msgid="2052499390128979920">"Uputi/primi SIP pozive"</string>
+    <string name="permdesc_use_sip" msgid="2297804849860225257">"Dozvoljava aplikaciji upućivanje i prijem SIP poziva."</string>
+    <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"registriraj nove telekom SMS veze"</string>
+    <string name="permdesc_register_sim_subscription" msgid="2138909035926222911">"Dozvoljava aplikaciji da registrira nove telekom SIM veze."</string>
+    <string name="permlab_register_call_provider" msgid="108102120289029841">"registriraj nove telekom veze"</string>
+    <string name="permdesc_register_call_provider" msgid="7034310263521081388">"Dozvoljava aplikaciji da registrira nove telekom veze."</string>
+    <string name="permlab_connection_manager" msgid="1116193254522105375">"upravljaj telekom vezama"</string>
+    <string name="permdesc_connection_manager" msgid="5925480810356483565">"Dozvoljava aplikacijama upravljanje telekom vezama."</string>
+    <string name="permlab_bind_incall_service" msgid="6773648341975287125">"vrši interakciju s ekranom tokom poziva"</string>
+    <string name="permdesc_bind_incall_service" msgid="8343471381323215005">"Dozvoljava aplikaciji da kontrolira kada i kako korisnik vidi ekran tokom poziva."</string>
+    <string name="permlab_bind_connection_service" msgid="3557341439297014940">"vrši interakciju s telefonskim uslugama"</string>
+    <string name="permdesc_bind_connection_service" msgid="4008754499822478114">"Dozvoljava aplikaciji interakciju s telefonskim uslugama za upućivanje/prijem poziva."</string>
+    <string name="permlab_control_incall_experience" msgid="9061024437607777619">"omogući opcije tokom poziva"</string>
+    <string name="permdesc_control_incall_experience" msgid="915159066039828124">"Dozvoljava aplikaciji da omogući opcije tokom poziva."</string>
+    <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"čitanje historije korištenja mreže"</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="7689060749819126472">"Dozvoljava aplikaciji da pročita istoriju korištenja mreže za određene mreže i aplikacije."</string>
+    <string name="permlab_manageNetworkPolicy" msgid="2562053592339859990">"upravljanje mrežnim pravilima"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"Dozvoljava aplikaciji upravljanje mrežnim pravilima i određivanje pravila koja se odnose na aplikacije."</string>
+    <string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"izmjena obračunavanja korištenja mreže"</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"Dozvoljava aplikaciji izmjenu načina na koji aplikacije koriste mreže. Nije namijenjeno za uobičajene aplikacije."</string>
+    <string name="permlab_accessNotifications" msgid="7673416487873432268">"pristup obavještenjima"</string>
+    <string name="permdesc_accessNotifications" msgid="458457742683431387">"Omogućava aplikaciji preuzimanje, ispitivanje i brisanje obavještenja, uključujući i ona koja su objavile druge aplikacije."</string>
+    <string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"povezivanje sa uslugom za slušanje obavještenja"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Omogućava vlasniku povezivanje s interfejsom najvišeg nivoa u servisu za slušanje obavještenja. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"poveži sa servisom pružaoca uslova"</string>
+    <string name="permdesc_bindConditionProviderService" msgid="1680513931165058425">"Dozvoljava vlasniku povezivanje s interfejsom najvišeg nivoa u servisu pružaoca uslova. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_bindDreamService" msgid="4153646965978563462">"poveži sa servisom za čuvanje ekrana"</string>
+    <string name="permdesc_bindDreamService" msgid="7325825272223347863">"Dozvoljava vlasniku povezivanje s interfejsom najvišeg nivoa u servisu za čuvanje ekrana. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="3699600833975117478">"pokretanje operaterove aplikacije za konfiguraciju"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Omogućava vlasniku pokretanje aplikacije za konfiguraciju koju je obezbijedio operater. Nije potrebno za normalne aplikacije."</string>
+    <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"slušanje informacija o stanju mreže"</string>
+    <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Omogućava aplikaciji slušanje informacije o stanju mreže. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"promijeni kalibraciju ulaznog uređaja"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Dozvoljava aplikaciji kalibriranje parametara dodirnog ekrana. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"pristupi DRM certifikatima"</string>
+    <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"Dozvoljava aplikaciji da obezbijedi i koristi DRM certifikate. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_handoverStatus" msgid="7820353257219300883">"prijem statusa prebacivanja preko Android prebacivanja"</string>
+    <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Dozvoljava aplikaciji prijem informacija o trenutnim prijenosima putem funkcije Android Beam"</string>
+    <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"ukloni DRM certifikate"</string>
+    <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Dozvoljava aplikaciji da ukloni DRM certifikate. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"poveži sa servisom za poruke operatera"</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Dozvoljava vlasniku povezivanje s interfejsom najvišeg nivoa u servisu za poruke operatera. Nije potrebno za obične aplikacije."</string>
+    <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"povezivanje na usluge operatera"</string>
+    <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Omogućava vlasniku povezivanje sa uslugama operatera. Obično nije potrebno za obične aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="4247510821662059671">"pristup opciji Ne ometaj"</string>
+    <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Omogućava aplikaciji da čita i upisuje konfiguraciju opcije Ne ometaj."</string>
+    <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavljanje pravila za lozinke"</string>
+    <string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN kodovima."</string>
+    <string name="policylab_watchLogin" msgid="914130646942199503">"Prati pokušaje otključavanja ekrana"</string>
+    <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Prati broj pogrešno unijetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše sve podatke s njega ukoliko se previše puta unese pogrešna lozinka."</string>
+    <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Prati koliko puta je lozinka neispravno otkucana prilikom otključavanja ekrana i zaključaj TV ili izbriši sve podatke s TV-a ako se lozinka neispravno ukuca previše puta."</string>
+    <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Prati broj pogrešno unesenih lozinki prilikom otključavanja ekrana i zaključava telefon ili briše sve podatke s telefona ukoliko se previše puta unese pogrešna lozinka."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Prati broj neispravnih lozinki koje su unijete za otključavanje ekrana te zaključava tablet ili briše sve podatke ovog korisnika ukoliko je unijeto previše neispravnih lozinki."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Prati broj neispravnih lozinki koje su unijete za otključavanje ekrana te zaključava TV ili briše sve podatke ovog korisnika ukoliko je unijeto previše neispravnih lozinki."</string>
+    <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Prati broj neispravnih lozinki koje su unijete za otključavanje ekrana te zaključava telefon ili briše sve podatke ovog korisnika ukoliko je unijeto previše neispravnih lozinki."</string>
+    <string name="policylab_resetPassword" msgid="4934707632423915395">"Promijeni zaključavanje ekrana"</string>
+    <string name="policydesc_resetPassword" msgid="1278323891710619128">"Mijenja zaključavanje ekrana."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Zaključava ekran"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrolira kako i kada se ekran zaključava."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Briše sve podatke"</string>
+    <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Briše podatke s tableta bez upozorenja tako što ga vraća na fabričke postavke."</string>
+    <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Bez upozorenja obriši sve podatke s TV-a vraćanjem na fabričke postavke."</string>
+    <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Briše podatke s telefona bez upozorenja vraćanjem telefona na fabričke postavke."</string>
+    <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Izbriši podatke korisnika"</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Bez upozorenja briše podatke ovog korisnika sa ovog tableta."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Bez upozorenja briše podatke ovog korisnika sa ovog TV-a."</string>
+    <string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Bez upozorenja briše podatke ovog korisnika sa ovog telefona."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Postavlja globalni proksi uređaja"</string>
+    <string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Postavlja globalni proksi uređaja koji će se koristiti dok su smjernice omogućene. Samo vlasnik uređaja može postaviti globalni proksi."</string>
+    <string name="policylab_expirePassword" msgid="5610055012328825874">"Postavi isteknuće lozinke za zaključavanje ekrana"</string>
+    <string name="policydesc_expirePassword" msgid="5367525762204416046">"Mijenja koliko često se lozinka za zaključavanje ekrana, PIN ili obrazac moraju promijeniti."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Podešava šifriranje pohrane"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Zahtijeva šifriranje pohranjenih podataka aplikacije."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Isključuje kamere"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Sprečava korištenje svih kamera uređaja."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Onemog. neke funk. zak. ekrana"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Spriječava korištenje nekih funkcija za zaključavanje ekrana."</string>
+  <string-array name="phoneTypes">
+    <item msgid="8901098336658710359">"Kuća"</item>
+    <item msgid="869923650527136615">"Mobilni"</item>
+    <item msgid="7897544654242874543">"Poslovni"</item>
+    <item msgid="1103601433382158155">"Poslovni faks"</item>
+    <item msgid="1735177144948329370">"Kućni faks"</item>
+    <item msgid="603878674477207394">"Pejdžer"</item>
+    <item msgid="1650824275177931637">"Ostalo"</item>
+    <item msgid="9192514806975898961">"Dodatno"</item>
+  </string-array>
+  <string-array name="emailAddressTypes">
+    <item msgid="8073994352956129127">"Kućni"</item>
+    <item msgid="7084237356602625604">"Poslovni"</item>
+    <item msgid="1112044410659011023">"Ostali"</item>
+    <item msgid="2374913952870110618">"Dodatni"</item>
+  </string-array>
+  <string-array name="postalAddressTypes">
+    <item msgid="6880257626740047286">"Kuća"</item>
+    <item msgid="5629153956045109251">"Posao"</item>
+    <item msgid="4966604264500343469">"Ostalo"</item>
+    <item msgid="4932682847595299369">"Dodatno"</item>
+  </string-array>
+  <string-array name="imAddressTypes">
+    <item msgid="1738585194601476694">"Kućni"</item>
+    <item msgid="1359644565647383708">"Poslovni"</item>
+    <item msgid="7868549401053615677">"Ostali"</item>
+    <item msgid="3145118944639869809">"Dodatni"</item>
+  </string-array>
+  <string-array name="organizationTypes">
+    <item msgid="7546335612189115615">"Posao"</item>
+    <item msgid="4378074129049520373">"Ostalo"</item>
+    <item msgid="3455047468583965104">"Dodatno"</item>
+  </string-array>
+  <string-array name="imProtocols">
+    <item msgid="8595261363518459565">"AIM"</item>
+    <item msgid="7390473628275490700">"Windows Live"</item>
+    <item msgid="7882877134931458217">"Yahoo"</item>
+    <item msgid="5035376313200585242">"Skype"</item>
+    <item msgid="7532363178459444943">"QQ"</item>
+    <item msgid="3713441034299660749">"Google Talk"</item>
+    <item msgid="2506857312718630823">"ICQ"</item>
+    <item msgid="1648797903785279353">"Jabber"</item>
+  </string-array>
+    <string name="phoneTypeCustom" msgid="1644738059053355820">"Prilagođeno"</string>
+    <string name="phoneTypeHome" msgid="2570923463033985887">"Kuća"</string>
+    <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobilni"</string>
+    <string name="phoneTypeWork" msgid="8863939667059911633">"Posao"</string>
+    <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Poslovni faks"</string>
+    <string name="phoneTypeFaxHome" msgid="2067265972322971467">"Kućni faks"</string>
+    <string name="phoneTypePager" msgid="7582359955394921732">"Pejdžer"</string>
+    <string name="phoneTypeOther" msgid="1544425847868765990">"Ostalo"</string>
+    <string name="phoneTypeCallback" msgid="2712175203065678206">"Povratni poziv"</string>
+    <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string>
+    <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Glavni broj kompanije"</string>
+    <string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
+    <string name="phoneTypeMain" msgid="6766137010628326916">"Glavni"</string>
+    <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Drugi faks"</string>
+    <string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
+    <string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string>
+    <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
+    <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Posao mobilni"</string>
+    <string name="phoneTypeWorkPager" msgid="649938731231157056">"Poslovni pejdžer"</string>
+    <string name="phoneTypeAssistant" msgid="5596772636128562884">"Pomoćnik"</string>
+    <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
+    <string name="eventTypeCustom" msgid="7837586198458073404">"Prilagođeno"</string>
+    <string name="eventTypeBirthday" msgid="2813379844211390740">"Rođendan"</string>
+    <string name="eventTypeAnniversary" msgid="3876779744518284000">"Godišnjica"</string>
+    <string name="eventTypeOther" msgid="7388178939010143077">"Ostalo"</string>
+    <string name="emailTypeCustom" msgid="8525960257804213846">"Prilagođeni"</string>
+    <string name="emailTypeHome" msgid="449227236140433919">"Kućni"</string>
+    <string name="emailTypeWork" msgid="3548058059601149973">"Poslovni"</string>
+    <string name="emailTypeOther" msgid="2923008695272639549">"Ostali"</string>
+    <string name="emailTypeMobile" msgid="119919005321166205">"Mobilni"</string>
+    <string name="postalTypeCustom" msgid="8903206903060479902">"Prilagođeno"</string>
+    <string name="postalTypeHome" msgid="8165756977184483097">"Kućna adresa"</string>
+    <string name="postalTypeWork" msgid="5268172772387694495">"Posao"</string>
+    <string name="postalTypeOther" msgid="2726111966623584341">"Ostalo"</string>
+    <string name="imTypeCustom" msgid="2074028755527826046">"Prilagođeno"</string>
+    <string name="imTypeHome" msgid="6241181032954263892">"Kuća"</string>
+    <string name="imTypeWork" msgid="1371489290242433090">"Posao"</string>
+    <string name="imTypeOther" msgid="5377007495735915478">"Ostalo"</string>
+    <string name="imProtocolCustom" msgid="6919453836618749992">"Prilagođeno"</string>
+    <string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
+    <string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
+    <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
+    <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
+    <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
+    <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
+    <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
+    <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
+    <string name="orgTypeWork" msgid="29268870505363872">"Posao"</string>
+    <string name="orgTypeOther" msgid="3951781131570124082">"Ostalo"</string>
+    <string name="orgTypeCustom" msgid="225523415372088322">"Prilagođeno"</string>
+    <string name="relationTypeCustom" msgid="3542403679827297300">"Prilagođeno"</string>
+    <string name="relationTypeAssistant" msgid="6274334825195379076">"Pomoćnik"</string>
+    <string name="relationTypeBrother" msgid="8757913506784067713">"Brat"</string>
+    <string name="relationTypeChild" msgid="1890746277276881626">"Dijete"</string>
+    <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Domaći partner"</string>
+    <string name="relationTypeFather" msgid="5228034687082050725">"Otac"</string>
+    <string name="relationTypeFriend" msgid="7313106762483391262">"Prijatelj"</string>
+    <string name="relationTypeManager" msgid="6365677861610137895">"Menadžer"</string>
+    <string name="relationTypeMother" msgid="4578571352962758304">"Majka"</string>
+    <string name="relationTypeParent" msgid="4755635567562925226">"Roditelj"</string>
+    <string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
+    <string name="relationTypeReferredBy" msgid="101573059844135524">"Uputio(la)"</string>
+    <string name="relationTypeRelative" msgid="1799819930085610271">"Rođak"</string>
+    <string name="relationTypeSister" msgid="1735983554479076481">"Sestra"</string>
+    <string name="relationTypeSpouse" msgid="394136939428698117">"Bračni partner"</string>
+    <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Prilagođeno"</string>
+    <string name="sipAddressTypeHome" msgid="6093598181069359295">"Kuća"</string>
+    <string name="sipAddressTypeWork" msgid="6920725730797099047">"Posao"</string>
+    <string name="sipAddressTypeOther" msgid="4408436162950119849">"Ostalo"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nije pronađena aplikacija za pregled ovog kontakta."</string>
+    <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"Unesite PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"Unesite PUK i novi PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"Novi PIN"</string>
+    <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"Dodirnite za unos lozinke"</font></string>
+    <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"Unesite lozinku za otključavanje tipkovnice"</string>
+    <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"Unesite PIN za otključavanje tipkovnice"</string>
+    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Pogrešan PIN."</string>
+    <string name="keyguard_label_text" msgid="861796461028298424">"Za otključavanje telefona pritisnite dugme Meni, pa dugme 0."</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"Broj za hitne slučajeve"</string>
+    <string name="lockscreen_carrier_default" msgid="6169005837238288522">"Nema mreže"</string>
+    <string name="lockscreen_screen_locked" msgid="7288443074806832904">"Ekran zaključan."</string>
+    <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pritisnite dugme Meni kako biste otključali uređaj ili obavili hitni poziv."</string>
+    <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pritisnite dugme Meni za otključavanje uređaja."</string>
+    <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Nacrtajte uzorak za otključavanje"</string>
+    <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitni slučaj"</string>
+    <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Povratak na poziv"</string>
+    <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ispravno!"</string>
+    <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Pokušajte ponovo"</string>
+    <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Pokušajte ponovo"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Premašen maksimalni broj pokušaja otključavanja licem"</string>
+    <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nema SIM kartice"</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nema SIM kartice u tabletu."</string>
+    <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Nema SIM kartice u TV-u."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Nema SIM kartice u telefonu."</string>
+    <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Umetnite SIM karticu."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM kartica nije umetnuta ili je uređaj ne može očitati. Umetnite SIM karticu."</string>
+    <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Neupotrebljiva SIM kartica."</string>
+    <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša SIM kartica je trajno onemogućena.\nKako biste dobili drugu SIM karticu, obratite se svom pružaocu bežičnih usluga."</string>
+    <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Prethodna numera"</string>
+    <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Sljedeća numera"</string>
+    <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pauziraj"</string>
+    <string name="lockscreen_transport_play_description" msgid="1901258823643886401">"Reproduciraj"</string>
+    <string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Zaustavi"</string>
+    <string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Premotaj"</string>
+    <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Ubrzaj"</string>
+    <string name="emergency_calls_only" msgid="6733978304386365407">"Samo hitni pozivi"</string>
+    <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Mreža zaključana"</string>
+    <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM kartica je zaključana PUK-om."</string>
+    <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Pogledajte Priručnik za korištenje ili kontaktirajte odjel za brigu o kupcima."</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">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Pogrešno ste unijeli svoju lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Pogrešno ste unijeli svoj PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati tablet prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Uzorak za otključavanje ste neispravno nacrtali <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, bit će zatraženo da TV otključate pomoću Google prijave.\n\n Pokušajte opet za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Pogrešno ste unijeli uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Nakon toga ćete morati otključati telefon prijavom na svoj Google račun.\n\n Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_2">%3$d</xliff:g>"</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Pogrešno ste pokušali otključati tablet <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Ukoliko ni tada ne uspijete otključati tablet, tablet će se vratiti na fabričke postavke i svi korisnički podaci bit će izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati TV. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, TV će biti vraćen na fabričke postavke i svi podaci korisnika bit će izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Pogrešno ste pokušali otključati telefon <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Možete pokušati još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta. Ukoliko ni tada ne uspijete otključati telefon, telefon će se vratiti na fabričke postavke i svi korisnički podaci bit će izgubljeni."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tablet" msgid="280873516493934365">"Pogrešno ste pokušali otključati tablet <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na fabričke postavke."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="tv" msgid="3195755534096192191">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati TV. TV će sada biti vraćen na fabričke postavke."</string>
+    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Pogrešno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na fabričke postavke."</string>
+    <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER">%d</xliff:g>"</string>
+    <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Zaboravili ste uzorak?"</string>
+    <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Otključavanje pomoću Google računa"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Previše puta ste pokušali otključati uređaj unosom uzorka"</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Kako biste otključali telefon, prijavite se na svoj Google račun."</string>
+    <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Korisničko ime (e-mail)"</string>
+    <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Lozinka"</string>
+    <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Prijava"</string>
+    <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Pogrešno korisničko ime ili lozinka."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Zaboravili ste korisničko ime ili lozinku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Provjera u toku..."</string>
+    <string name="lockscreen_unlock_label" msgid="737440483220667054">"Otključaj"</string>
+    <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Zvuk uključen"</string>
+    <string name="lockscreen_sound_off_label" msgid="996822825154319026">"Isključi zvuk"</string>
+    <string name="lockscreen_access_pattern_start" msgid="3941045502933142847">"Uzorak započet"</string>
+    <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Uzorak izbrisan"</string>
+    <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Ćelija dodana"</string>
+    <string name="lockscreen_access_pattern_cell_added_verbose" msgid="7264580781744026939">"Ćelija <xliff:g id="CELL_INDEX">%1$s</xliff:g> je dodana"</string>
+    <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Uzorak unesen"</string>
+    <string name="lockscreen_access_pattern_area" msgid="400813207572953209">"Oblast za unošenje obrasca."</string>
+    <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d od %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Dodaj widget."</string>
+    <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Prazno"</string>
+    <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Oblast za otključavanje je proširena."</string>
+    <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Oblast za otključavanje je smanjena."</string>
+    <string name="keyguard_accessibility_widget" msgid="6527131039741808240">"Widget za <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</string>
+    <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Biranje korisnika"</string>
+    <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+    <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string>
+    <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Upravljanje medijima"</string>
+    <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Promjena rasporeda widgeta je počela."</string>
+    <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Promjena rasporeda widgeta je završena."</string>
+    <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> je izbrisan."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Proširi oblast za otključavanje."</string>
+    <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Otključavanje pomoću klizača."</string>
+    <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Otključavanje uzorkom."</string>
+    <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Otključavanje licem."</string>
+    <string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Otključavanje pinom."</string>
+    <string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Otključavanje lozinkom."</string>
+    <string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Uzorak oblasti."</string>
+    <string name="keyguard_accessibility_slide_area" msgid="6736064494019979544">"Oblast za pomjeranje klizača."</string>
+    <string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
+    <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
+    <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
+    <string name="granularity_label_character" msgid="7336470535385009523">"znak"</string>
+    <string name="granularity_label_word" msgid="7075570328374918660">"riječ"</string>
+    <string name="granularity_label_link" msgid="5815508880782488267">"link"</string>
+    <string name="granularity_label_line" msgid="5764267235026120888">"linija"</string>
+    <string name="factorytest_failed" msgid="5410270329114212041">"Fabrički test nije uspio"</string>
+    <string name="factorytest_not_system" msgid="4435201656767276723">"Akcija FACTORY_TEST podržana je samo za pakete instalirane u facsikli /system/app."</string>
+    <string name="factorytest_no_action" msgid="872991874799998561">"Nije pronađen paket koji omogućava akciju FACTORY_TEST."</string>
+    <string name="factorytest_reboot" msgid="6320168203050791643">"Ponovno pokretanje"</string>
+    <string name="js_dialog_title" msgid="1987483977834603872">"Stranica na \"<xliff:g id="TITLE">%s</xliff:g>\" kaže:"</string>
+    <string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
+    <string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrdite navigaciju"</string>
+    <string name="js_dialog_before_unload_positive_button" msgid="3112752010600484130">"Napusti ovu stranicu"</string>
+    <string name="js_dialog_before_unload_negative_button" msgid="5614861293026099715">"Ostani na ovoj stranici"</string>
+    <string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\n Da li ste sigurni da želite napustiti ovu stranicu?"</string>
+    <string name="save_password_label" msgid="6860261758665825069">"Potvrdite"</string>
+    <string name="double_tap_toast" msgid="4595046515400268881">"Savjet: Dodirnite ekran dva puta za uvećanje ili smanjenje prikaza."</string>
+    <string name="autofill_this_form" msgid="4616758841157816676">"Autofill"</string>
+    <string name="setup_autofill" msgid="7103495070180590814">"Podesite Autofill"</string>
+    <string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
+    <string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
+    <string name="autofill_address_summary_separator" msgid="7483307893170324129">", "</string>
+    <string name="autofill_address_summary_format" msgid="4874459455786827344">"$1$2$3"</string>
+    <string name="autofill_province" msgid="2231806553863422300">"Pokrajina"</string>
+    <string name="autofill_postal_code" msgid="4696430407689377108">"Poštanski broj"</string>
+    <string name="autofill_state" msgid="6988894195520044613">"Država"</string>
+    <string name="autofill_zip_code" msgid="8697544592627322946">"Poštanski broj"</string>
+    <string name="autofill_county" msgid="237073771020362891">"Okrug"</string>
+    <string name="autofill_island" msgid="4020100875984667025">"Ostrvo"</string>
+    <string name="autofill_district" msgid="8400735073392267672">"Oblast"</string>
+    <string name="autofill_department" msgid="5343279462564453309">"Odsjek"</string>
+    <string name="autofill_prefecture" msgid="2028499485065800419">"Prefektura"</string>
+    <string name="autofill_parish" msgid="8202206105468820057">"Parohija"</string>
+    <string name="autofill_area" msgid="3547409050889952423">"Oblast"</string>
+    <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
+    <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"čitanje internet oznaka i historije"</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Omogućava aplikaciji čitanje historije URL-ova koje je preglednik posjetio, kao i svih  oznaka preglednika. Napomena: ovu dozvolu ne mogu iskoristiti preglednici trećih strana ili druge aplikacije koje imaju mogućnost pregledanja interneta."</string>
+    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"pisanje internet oznaka i historije"</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Omogućava aplikaciji da izmijeni historiju ili oznake preglednika koji su pohranjeni na vašem tabletu. Ovim se aplikaciji može omogućiti da izbriše ili izmijeni podatke preglednika. Napomena: ovu dozvolu ne mogu koristiti preglednici trećih strana ili druge aplikacije koje imaju mogućnost pregledanja interneta."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Dozvoljava aplikaciji izmjenu historije ili oznaka preglednika pohranjenih na TV-u. Ovim se aplikaciji može omogućiti brisanje ili izmjena podataka preglednika. Napomena: ovu dozvolu ne mogu iskoristiti preglednici trećih strana ili druge aplikacije koje imaju mogućnost pregleda interneta."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Omogućava aplikaciji da izmijeni historiju ili oznake preglednika koji su pohranjeni na vašem telefonu. Ovim se aplikaciji može omogućiti da izbriše ili izmijeni podatke preglednika. Napomena: ovu dozvolu ne mogu koristiti preglednika trećih strana ili druge aplikacije koje imaju mogućnost pregledanja interneta."</string>
+    <string name="permlab_setAlarm" msgid="1379294556362091814">"postavljanje alarma"</string>
+    <string name="permdesc_setAlarm" msgid="316392039157473848">"Dozvoljava aplikaciji postavljanje alarma u instaliranom budilniku. Moguće je da neki budilnici neće primijeniti ovu funkciju."</string>
+    <string name="permlab_addVoicemail" msgid="5525660026090959044">"dodavanje govorne pošte"</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Dozvoljava aplikaciji dodavanje poruka u vašu ulaznu govornu poštu."</string>
+    <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"izmjena geolokacijskih dozvola preglednika"</string>
+    <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Dozvoljava aplikaciji mijenjanje geolokacijskih dozvola pretraživača. Zlonamjerne aplikacije mogu to iskoristiti i dozvoliti slanje informacija o lokaciji proizvoljnim web stranicama."</string>
+    <string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu lozinku?"</string>
+    <string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
+    <string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
+    <string name="save_password_never" msgid="8274330296785855105">"Nikad"</string>
+    <string name="open_permission_deny" msgid="7374036708316629800">"Nemate dozvolu za otvaranje ove stranice."</string>
+    <string name="text_copied" msgid="4985729524670131385">"Tekst kopiran u međuspremnik."</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Više"</string>
+    <string name="prepend_shortcut_label" msgid="2572214461676015642">"Meni+"</string>
+    <string name="menu_space_shortcut_label" msgid="2410328639272162537">"razmak"</string>
+    <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"potvrdi"</string>
+    <string name="menu_delete_shortcut_label" msgid="3658178007202748164">"izbriši"</string>
+    <string name="search_go" msgid="8298016669822141719">"Traži"</string>
+    <string name="search_hint" msgid="1733947260773056054">"Pretraži..."</string>
+    <string name="searchview_description_search" msgid="6749826639098512120">"Traži"</string>
+    <string name="searchview_description_query" msgid="5911778593125355124">"Upit za pretragu"</string>
+    <string name="searchview_description_clear" msgid="1330281990951833033">"Obriši upit"</string>
+    <string name="searchview_description_submit" msgid="2688450133297983542">"Potvrditi upit"</string>
+    <string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno pretraživanje"</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Želite li omogućiti Istraživanje dodirom?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete čuti ili vidjeti opise onoga što vam je pod prstom ili praviti pokrete za interakciju sa tabletom."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Usluga <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> želi omogućiti Istraživanje dodirom. Kada je Istraživanje dodirom uključeno, možete čuti ili vidjeti opise onoga što vam je pod prstom ili praviti pokrete za interakciju sa telefonom."</string>
+    <string name="oneMonthDurationPast" msgid="7396384508953779925">"Prije mjesec dana"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Prije više od mjesec dana"</string>
+    <plurals name="last_num_days" formatted="false" msgid="5104533550723932025">
+      <item quantity="one">Prethodni <xliff:g id="COUNT_1">%d</xliff:g> dan</item>
+      <item quantity="few">Prethodna <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+      <item quantity="other">Prethodnih <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+    </plurals>
+    <string name="last_month" msgid="3959346739979055432">"Prošli mjesec"</string>
+    <string name="older" msgid="5211975022815554840">"Starije"</string>
+    <string name="preposition_for_date" msgid="9093949757757445117">"datuma <xliff:g id="DATE">%s</xliff:g>"</string>
+    <string name="preposition_for_time" msgid="5506831244263083793">"u <xliff:g id="TIME">%s</xliff:g>"</string>
+    <string name="preposition_for_year" msgid="5040395640711867177">"godine <xliff:g id="YEAR">%s</xliff:g>"</string>
+    <string name="day" msgid="8144195776058119424">"dan"</string>
+    <string name="days" msgid="4774547661021344602">"dana"</string>
+    <string name="hour" msgid="2126771916426189481">"sat"</string>
+    <string name="hours" msgid="894424005266852993">"sati"</string>
+    <string name="minute" msgid="9148878657703769868">"minuta"</string>
+    <string name="minutes" msgid="5646001005827034509">"minute"</string>
+    <string name="second" msgid="3184235808021478">"sekunda"</string>
+    <string name="seconds" msgid="3161515347216589235">"sekunde"</string>
+    <string name="week" msgid="5617961537173061583">"sedmica"</string>
+    <string name="weeks" msgid="6509623834583944518">"sedmice"</string>
+    <string name="year" msgid="4001118221013892076">"godina"</string>
+    <string name="years" msgid="6881577717993213522">"godine"</string>
+    <plurals name="duration_seconds" formatted="false" msgid="4527986939729687805">
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> sekunda</item>
+      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> sekunde</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> sekundi</item>
+    </plurals>
+    <plurals name="duration_minutes" formatted="false" msgid="643786953939956125">
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> minuta</item>
+      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> minute</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> minuta</item>
+    </plurals>
+    <plurals name="duration_hours" formatted="false" msgid="6826233369186668274">
+      <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> sat</item>
+      <item quantity="few"><xliff:g id="COUNT">%d</xliff:g> sata</item>
+      <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> sati</item>
+    </plurals>
+    <string name="VideoView_error_title" msgid="3534509135438353077">"Problem sa prikazom video sadržaja"</string>
+    <string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Prijenos ovog video sadržaja ne može se izvršiti na ovom uređaju."</string>
+    <string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Greška prilikom reproduciranja video sadržaja."</string>
+    <string name="VideoView_error_button" msgid="2822238215100679592">"Uredu"</string>
+    <string name="relative_time" msgid="1818557177829411417">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+    <string name="noon" msgid="7245353528818587908">"podne"</string>
+    <string name="Noon" msgid="3342127745230013127">"Podne"</string>
+    <string name="midnight" msgid="7166259508850457595">"ponoć"</string>
+    <string name="Midnight" msgid="5630806906897892201">"Ponoć"</string>
+    <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
+    <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+    <string name="selectAll" msgid="6876518925844129331">"Odaberi sve"</string>
+    <string name="cut" msgid="3092569408438626261">"Izreži"</string>
+    <string name="copy" msgid="2681946229533511987">"Kopirajte"</string>
+    <string name="paste" msgid="5629880836805036433">"Zalijepi"</string>
+    <string name="paste_as_plain_text" msgid="5427792741908010675">"Zalijepi kao neformatiran tekst"</string>
+    <string name="replace" msgid="5781686059063148930">"Zamijeniti..."</string>
+    <string name="delete" msgid="6098684844021697789">"Izbrišite"</string>
+    <string name="copyUrl" msgid="2538211579596067402">"Kopirajte URL"</string>
+    <string name="selectTextMode" msgid="1018691815143165326">"Odaberi tekst"</string>
+    <string name="undo" msgid="7905788502491742328">"Vrati"</string>
+    <string name="redo" msgid="7759464876566803888">"Ponovo uradi"</string>
+    <string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
+    <string name="addToDictionary" msgid="4352161534510057874">"Dodaj u rječnik"</string>
+    <string name="deleteText" msgid="6979668428458199034">"Izbriši"</string>
+    <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
+    <string name="editTextMenuTitle" msgid="4909135564941815494">"Akcije za tekst"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke funkcije sistema možda neće raditi"</string>
+    <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nema dovoljno prostora za sistem. Obezbijedite 250MB slobodnog prostora i ponovo pokrenite uređaj."</string>
+    <string name="app_running_notification_title" msgid="8718335121060787914">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta"</string>
+    <string name="app_running_notification_text" msgid="4653586947747330058">"Dodirnite za više informacija ili da zaustavite aplikaciju."</string>
+    <string name="ok" msgid="5970060430562524910">"Uredu"</string>
+    <string name="cancel" msgid="6442560571259935130">"Prekini"</string>
+    <string name="yes" msgid="5362982303337969312">"Uredu"</string>
+    <string name="no" msgid="5141531044935541497">"Prekini"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Pažnja"</string>
+    <string name="loading" msgid="7933681260296021180">"Učitavanje..."</string>
+    <string name="capital_on" msgid="1544682755514494298">"Uključeno"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Isključeno"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Izvrši akciju koristeći"</string>
+    <string name="whichApplicationNamed" msgid="8260158865936942783">"Dovršite akciju koristeći %1$s"</string>
+    <string name="whichViewApplication" msgid="3272778576700572102">"Otvori koristeći"</string>
+    <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvori koristeći %1$s"</string>
+    <string name="whichEditApplication" msgid="144727838241402655">"Uredi koristeći"</string>
+    <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Uredi koristeći %1$s"</string>
+    <string name="whichSendApplication" msgid="6902512414057341668">"Podijeli koristeći"</string>
+    <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Podijeli koristeći %1$s"</string>
+    <string name="whichHomeApplication" msgid="4307587691506919691">"Odaberi glavnu aplikaciju"</string>
+    <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Koristi %1$s kao glavnu aplikaciju"</string>
+    <string name="alwaysUse" msgid="4583018368000610438">"Koristiti kao zadanu rezoluciju za ovu akciju."</string>
+    <string name="use_a_different_app" msgid="8134926230585710243">"Koristi drugu aplikaciju"</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Obrišite zadane opcije u meniju Postavke sistema &gt; Aplikacije &gt; Preuzete aplikacije."</string>
+    <string name="chooseActivity" msgid="7486876147751803333">"Odaberite akciju"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"Odaberite aplikaciju za USB uređaj"</string>
+    <string name="noApplications" msgid="2991814273936504689">"Nijedna aplikacija ne može izvršiti ovu akciju."</string>
     <string name="aerr_application" msgid="250320989337856518">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
-    <string name="aerr_process" msgid="6201597323218674729">"Aplikacija <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljena"</string>
+    <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
     <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
     <string name="aerr_restart" msgid="9001379185665886595">"Ponovo pokreni aplikaciju"</string>
@@ -1709,1161 +931,660 @@
     <string name="anr_activity_process" msgid="1622382268908620314">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ne reaguje"</string>
     <string name="anr_application_process" msgid="6417199034861140083">"<xliff:g id="APPLICATION">%1$s</xliff:g> ne reaguje"</string>
     <string name="anr_process" msgid="6156880875555921105">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> ne reaguje"</string>
-    <!-- no translation found for force_close (8346072094521265605) -->
-    <skip />
-    <!-- no translation found for report (4060218260984795706) -->
-    <skip />
-    <!-- no translation found for wait (7147118217226317732) -->
-    <skip />
-    <!-- no translation found for webpage_unresponsive (3272758351138122503) -->
-    <skip />
-    <!-- no translation found for launch_warning_title (1547997780506713581) -->
-    <skip />
-    <!-- no translation found for launch_warning_replace (6202498949970281412) -->
-    <skip />
-    <!-- no translation found for launch_warning_original (188102023021668683) -->
-    <skip />
-    <!-- no translation found for screen_compat_mode_scale (3202955667675944499) -->
-    <skip />
-    <!-- no translation found for screen_compat_mode_show (4013878876486655892) -->
-    <skip />
-    <!-- no translation found for screen_compat_mode_hint (1064524084543304459) -->
-    <skip />
-    <!-- no translation found for smv_application (3307209192155442829) -->
-    <skip />
-    <!-- no translation found for smv_process (5120397012047462446) -->
-    <skip />
-    <!-- no translation found for android_upgrading_title (1584192285441405746) -->
-    <skip />
-    <!-- no translation found for android_start_title (8418054686415318207) -->
-    <skip />
-    <!-- no translation found for android_upgrading_fstrim (8036718871534640010) -->
-    <skip />
-    <!-- no translation found for android_upgrading_apk (7904042682111526169) -->
-    <skip />
-    <!-- no translation found for android_preparing_apk (8162599310274079154) -->
-    <skip />
-    <!-- no translation found for android_upgrading_starting_apps (451464516346926713) -->
-    <skip />
-    <!-- no translation found for android_upgrading_complete (1405954754112999229) -->
-    <skip />
-    <!-- no translation found for heavy_weight_notification (9087063985776626166) -->
-    <skip />
-    <!-- no translation found for heavy_weight_notification_detail (1721681741617898865) -->
-    <skip />
-    <!-- no translation found for heavy_weight_switcher_title (7153167085403298169) -->
-    <skip />
-    <!-- no translation found for heavy_weight_switcher_text (7022631924534406403) -->
-    <skip />
-    <!-- no translation found for old_app_action (493129172238566282) -->
-    <skip />
-    <!-- no translation found for old_app_description (2082094275580358049) -->
-    <skip />
-    <!-- no translation found for new_app_action (5472756926945440706) -->
-    <skip />
-    <!-- no translation found for new_app_description (1932143598371537340) -->
-    <skip />
-    <!-- no translation found for dump_heap_notification (2618183274836056542) -->
-    <skip />
-    <!-- no translation found for dump_heap_notification_detail (2075673362317481664) -->
-    <skip />
-    <!-- no translation found for dump_heap_title (5864292264307651673) -->
-    <skip />
-    <!-- no translation found for dump_heap_text (4809417337240334941) -->
-    <skip />
-    <!-- no translation found for sendText (5209874571959469142) -->
-    <skip />
-    <!-- no translation found for volume_ringtone (6885421406845734650) -->
-    <skip />
-    <!-- no translation found for volume_music (5421651157138628171) -->
-    <skip />
-    <!-- no translation found for volume_music_hint_playing_through_bluetooth (9165984379394601533) -->
-    <skip />
-    <!-- no translation found for volume_music_hint_silent_ringtone_selected (8310739960973156272) -->
-    <skip />
-    <!-- no translation found for volume_call (3941680041282788711) -->
-    <skip />
-    <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
-    <skip />
-    <!-- no translation found for volume_alarm (1985191616042689100) -->
-    <skip />
-    <!-- no translation found for volume_notification (2422265656744276715) -->
-    <skip />
-    <!-- no translation found for volume_unknown (1400219669770445902) -->
-    <skip />
-    <!-- no translation found for volume_icon_description_bluetooth (6538894177255964340) -->
-    <skip />
-    <!-- no translation found for volume_icon_description_ringer (3326003847006162496) -->
-    <skip />
-    <!-- no translation found for volume_icon_description_incall (8890073218154543397) -->
-    <skip />
-    <!-- no translation found for volume_icon_description_media (4217311719665194215) -->
-    <skip />
-    <!-- no translation found for volume_icon_description_notification (7044986546477282274) -->
-    <skip />
-    <!-- no translation found for ringtone_default (3789758980357696936) -->
-    <skip />
-    <!-- no translation found for ringtone_default_with_actual (8129563480895990372) -->
-    <skip />
-    <!-- no translation found for ringtone_silent (7937634392408977062) -->
-    <skip />
-    <!-- no translation found for ringtone_picker_title (3515143939175119094) -->
-    <skip />
-    <!-- no translation found for ringtone_unknown (5477919988701784788) -->
-    <skip />
-    <!-- no translation found for wifi_available (7900333017752027322) -->
-    <!-- no translation found for wifi_available_detailed (1140699367193975606) -->
-    <!-- no translation found for wifi_available_sign_in (9157196203958866662) -->
-    <skip />
-    <!-- no translation found for network_available_sign_in (1848877297365446605) -->
-    <skip />
+    <string name="force_close" msgid="8346072094521265605">"Uredu"</string>
+    <string name="report" msgid="4060218260984795706">"Prijavi"</string>
+    <string name="wait" msgid="7147118217226317732">"Sačekaj"</string>
+    <string name="webpage_unresponsive" msgid="3272758351138122503">"Stranica ne reagira.\n\nŽelite li je zatvoriti?"</string>
+    <string name="launch_warning_title" msgid="1547997780506713581">"Aplikacija preusmjerena"</string>
+    <string name="launch_warning_replace" msgid="6202498949970281412">"Sada je pokrenuta aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="launch_warning_original" msgid="188102023021668683">"Izvorno je pokrenuta aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Razmjer"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Uvijek prikaži"</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Ponovo omogućite ovu opciju u meniju Postavke sistema &gt; Aplikacije &gt; Preuzete aplikacije."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) prekršila je vlastita StrictMode pravila."</string>
+    <string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> prekršio je vlastita StrictMode pravila."</string>
+    <string name="android_upgrading_title" msgid="1584192285441405746">"Nadogradnja sistema Android u toku..."</string>
+    <string name="android_start_title" msgid="8418054686415318207">"Android se pokreće..."</string>
+    <string name="android_upgrading_fstrim" msgid="8036718871534640010">"Optimiziranje pohrane."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Optimiziranje aplikacije <xliff:g id="NUMBER_0">%1$d</xliff:g> od <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_preparing_apk" msgid="8162599310274079154">"Priprema se <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Pokretanje aplikacija."</string>
+    <string name="android_upgrading_complete" msgid="1405954754112999229">"Pokretanje pri kraju."</string>
+    <string name="heavy_weight_notification" msgid="9087063985776626166">"Pokrenuta je aplikacija <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Dodirnite kako biste otvorili aplikaciju"</string>
+    <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Želite se prebaciti na drugu aplikaciju?"</string>
+    <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Već je pokrenuta jedna aplikacija koju morate zaustaviti prije pokretanja nove."</string>
+    <string name="old_app_action" msgid="493129172238566282">"Vrati se na aplikaciju <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Ne pokretati novu aplikaciju."</string>
+    <string name="new_app_action" msgid="5472756926945440706">"Pokreni <xliff:g id="OLD_APP">%1$s</xliff:g>"</string>
+    <string name="new_app_description" msgid="1932143598371537340">"Zaustaviti staru aplikaciju bez spašavanja podataka."</string>
+    <string name="dump_heap_notification" msgid="2618183274836056542">"<xliff:g id="PROC">%1$s</xliff:g> premašuje ograničenje memorije"</string>
+    <string name="dump_heap_notification_detail" msgid="2075673362317481664">"Snimak dinamičkog dijela memorije je napravljen; dodirnite za dijeljenje"</string>
+    <string name="dump_heap_title" msgid="5864292264307651673">"Želite li dijeliti snimak dinamičkog dijela memorije?"</string>
+    <string name="dump_heap_text" msgid="4809417337240334941">"Proces <xliff:g id="PROC">%1$s</xliff:g> je premašio ograničenje procesne memorije od <xliff:g id="SIZE">%2$s</xliff:g>. Snimak dinamičkog dijela memorije vam je dostupan i možete ga dijeliti sa njegovim programerom. Budite oprezni: ovaj snimak dinamičkog dijela memorije može sadržavati vaše lične podatke kojima aplikacija ima pristup."</string>
+    <string name="sendText" msgid="5209874571959469142">"Biranje akcije za tekst"</string>
+    <string name="volume_ringtone" msgid="6885421406845734650">"Jačina zvuka zvona"</string>
+    <string name="volume_music" msgid="5421651157138628171">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Medijski sadržaj se reproducira preko Bluetooth veze"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Postavljena nečujna melodija zvona"</string>
+    <string name="volume_call" msgid="3941680041282788711">"Jačina zvuka tokom poziva"</string>
+    <string name="volume_bluetooth_call" msgid="2002891926351151534">"Jačina zvuka tokom poziva preko Bluetooth veze"</string>
+    <string name="volume_alarm" msgid="1985191616042689100">"Jačina zvuka alarma"</string>
+    <string name="volume_notification" msgid="2422265656744276715">"Jačina zvuka za obavještenja"</string>
+    <string name="volume_unknown" msgid="1400219669770445902">"Jačina zvuka"</string>
+    <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Jačina zvuka za Bluetooth vezu"</string>
+    <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Jačina zvuka melodije"</string>
+    <string name="volume_icon_description_incall" msgid="8890073218154543397">"Jačina zvuka tokom poziva"</string>
+    <string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string>
+    <string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string>
+    <string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
+    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Zadano zvono (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_silent" msgid="7937634392408977062">"Ne poduzimaj ništa"</string>
+    <string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
+    <string name="ringtone_unknown" msgid="5477919988701784788">"Nepoznato zvono"</string>
+    <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
+      <item quantity="one">Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
+      <item quantity="one">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="few">Otvorene Wi-Fi mreže su dostupne</item>
+      <item quantity="other">Otvorene Wi-Fi mreže su dostupne</item>
+    </plurals>
+    <string name="wifi_available_sign_in" msgid="9157196203958866662">"Prijavljivanje na Wi-Fi mrežu"</string>
+    <string name="network_available_sign_in" msgid="1848877297365446605">"Prijavite se na mrežu"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
-    <!-- no translation found for wifi_no_internet (8451173622563841546) -->
-    <skip />
-    <!-- no translation found for wifi_no_internet_detailed (7593858887662270131) -->
-    <skip />
-    <!-- no translation found for wifi_watchdog_network_disabled (7904214231651546347) -->
-    <skip />
-    <!-- no translation found for wifi_watchdog_network_disabled_detailed (5548780776418332675) -->
-    <skip />
-    <!-- no translation found for wifi_connect_alert_title (8455846016001810172) -->
-    <skip />
-    <!-- no translation found for wifi_connect_alert_message (6451273376815958922) -->
-    <skip />
-    <!-- no translation found for wifi_connect_default_application (7143109390475484319) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_turnon_message (2909250942299627244) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_failed_message (3763669677935623084) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_enabled_notification_title (2068321881673734886) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_enabled_notification_message (1638949953993894335) -->
-    <skip />
-    <!-- no translation found for accept (1645267259272829559) -->
-    <skip />
-    <!-- no translation found for decline (2112225451706137894) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_invitation_sent_title (1318975185112070734) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_invitation_to_connect_title (4958803948658533637) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_from_message (570389174731951769) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_to_message (248968974522044099) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_enter_pin_message (5920929550367828970) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_show_pin_message (8530563323880921094) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_frequency_conflict_message (8012981257742232475) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_frequency_conflict_message (3087858235069421128) -->
-    <skip />
-    <!-- no translation found for wifi_p2p_frequency_conflict_message (7363907213787469151) -->
-    <skip />
-    <!-- no translation found for select_character (3365550120617701745) -->
-    <skip />
-    <!-- no translation found for sms_control_title (7296612781128917719) -->
-    <skip />
-    <!-- no translation found for sms_control_message (3867899169651496433) -->
-    <skip />
-    <!-- no translation found for sms_control_yes (3663725993855816807) -->
-    <skip />
-    <!-- no translation found for sms_control_no (625438561395534982) -->
-    <skip />
-    <!-- no translation found for sms_short_code_confirm_message (1645436466285310855) -->
-    <skip />
-    <!-- no translation found for sms_short_code_details (5873295990846059400) -->
-    <skip />
-    <!-- no translation found for sms_premium_short_code_details (7869234868023975) -->
-    <skip />
-    <!-- no translation found for sms_short_code_confirm_allow (4458878637111023413) -->
-    <skip />
-    <!-- no translation found for sms_short_code_confirm_deny (2927389840209170706) -->
-    <skip />
-    <!-- no translation found for sms_short_code_remember_choice (5289538592272218136) -->
-    <skip />
-    <!-- no translation found for sms_short_code_remember_undo_instruction (4960944133052287484) -->
-    <skip />
-    <!-- no translation found for sms_short_code_confirm_always_allow (3241181154869493368) -->
-    <skip />
-    <!-- no translation found for sms_short_code_confirm_never_allow (446992765774269673) -->
-    <skip />
-    <!-- no translation found for sim_removed_title (6227712319223226185) -->
-    <skip />
-    <!-- no translation found for sim_removed_message (5450336489923274918) -->
-    <skip />
-    <!-- no translation found for sim_done_button (827949989369963775) -->
-    <skip />
-    <!-- no translation found for sim_added_title (3719670512889674693) -->
-    <skip />
-    <!-- no translation found for sim_added_message (7797975656153714319) -->
-    <skip />
-    <!-- no translation found for sim_restart_button (4722407842815232347) -->
-    <skip />
+    <string name="wifi_no_internet" msgid="8451173622563841546">"Wi-Fi nema pristup Internetu"</string>
+    <string name="wifi_no_internet_detailed" msgid="7593858887662270131">"Dodirnite za opcije"</string>
+    <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Problem prilikom spajanja na Wi-Fi mrežu"</string>
+    <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internet vezu."</string>
+    <string name="wifi_connect_alert_title" msgid="8455846016001810172">"Želite li dozvoliti povezivanje?"</string>
+    <string name="wifi_connect_alert_message" msgid="6451273376815958922">"Aplikacija %1$s se želi povezati na Wi-Fi mrežu %2$s"</string>
+    <string name="wifi_connect_default_application" msgid="7143109390475484319">"Aplikacija"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+    <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Pokreni Wi-Fi Direct. To će isključiti Wi-Fi klijenta/pristupnu tačku."</string>
+    <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Greška u pokretanju opcije Wi-Fi Direct."</string>
+    <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct je uključen"</string>
+    <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Dodirnite za postavke"</string>
+    <string name="accept" msgid="1645267259272829559">"Prihvati"</string>
+    <string name="decline" msgid="2112225451706137894">"Odbijte"</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozivnica poslana"</string>
+    <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Poziv za povezivanje"</string>
+    <string name="wifi_p2p_from_message" msgid="570389174731951769">"Pošiljalac:"</string>
+    <string name="wifi_p2p_to_message" msgid="248968974522044099">"Primalac:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Unesite potrebni PIN:"</string>
+    <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Tablet će privremeno prekinuti Wi-Fi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"TV će privremeno prekinuti Wi-Fi vezu dok je povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefon će privremeno prekinuti Wi-Fi vezu dok bude povezan s uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="select_character" msgid="3365550120617701745">"Umetni karakter"</string>
+    <string name="sms_control_title" msgid="7296612781128917719">"Slanje SMS poruka"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; šalje veliki broj SMS poruka. Da li želite dozvoliti ovoj aplikaciji da nastavi slanje poruka?"</string>
+    <string name="sms_control_yes" msgid="3663725993855816807">"Dozvoli"</string>
+    <string name="sms_control_no" msgid="625438561395534982">"Odbij"</string>
+    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; želi poslati poruku na adresu &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
+    <string name="sms_short_code_details" msgid="5873295990846059400">"Ovo "<b>"može uzrokovati troškove"</b>" na vašem računu za mobilne usluge."</string>
+    <string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"Ovo će uzrokovati troškove na vašem računu za mobilne usluge."</b></string>
+    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Pošalji"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Otkaži"</string>
+    <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Zapamti moj izbor"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Ovo možete kasnije promijeniti u meniju Postavke &gt; Aplikacije"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Uvijek dozvoli"</string>
+    <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nikada ne dozvoli"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM kartica uklonjena"</string>
+    <string name="sim_removed_message" msgid="5450336489923274918">"Mobilna mreža neće biti dostupna dok ponovo ne pokrenete uređaj s umetnutom važećom SIM karticom."</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM kartica dodana"</string>
+    <string name="sim_added_message" msgid="7797975656153714319">"Ponovo pokrenite uređaj da pristupite mobilnoj mreži."</string>
+    <string name="sim_restart_button" msgid="4722407842815232347">"Ponovo pokreni"</string>
     <string name="carrier_app_dialog_message" msgid="7066156088266319533">"Da bi nova SIM kartica ispravno radila, morate instalirati i otvoriti aplikaciju svog operatera."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"PREUZMI APLIKACIJU"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"NE SADA"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"Nova SIM kartica je umetnuta"</string>
     <string name="carrier_app_notification_text" msgid="1132487343346050225">"Dodirnite da biste postavili"</string>
-    <!-- no translation found for time_picker_dialog_title (8349362623068819295) -->
+    <string name="time_picker_dialog_title" msgid="8349362623068819295">"Postavljanje vremena"</string>
+    <string name="date_picker_dialog_title" msgid="5879450659453782278">"Postavljanje datuma"</string>
+    <string name="date_time_set" msgid="5777075614321087758">"Postaviti"</string>
+    <string name="date_time_done" msgid="2507683751759308828">"Završeno"</string>
+    <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff33b5e5">"NOVO: "</font></string>
+    <string name="perms_description_app" msgid="5139836143293299417">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> omogućava."</string>
+    <string name="no_permissions" msgid="7283357728219338112">"Nisu potrebne dozvole"</string>
+    <string name="perm_costs_money" msgid="4902470324142151116">"ovo se možda dodatno plaća"</string>
+    <string name="dlg_ok" msgid="7376953167039865701">"Uredu"</string>
+    <string name="usb_charging_notification_title" msgid="4004114449249406402">"USB za punjenje"</string>
+    <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB za prijenos fajlova"</string>
+    <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB za prijenos slika"</string>
+    <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB za MIDI"</string>
+    <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Uspostavljena veza sa USB pohranom"</string>
+    <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za više opcija."</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Uređaj za USB otklanjanje grešaka povezan"</string>
+    <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili USB otklanjanje grešaka."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
     <skip />
-    <!-- no translation found for date_picker_dialog_title (5879450659453782278) -->
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
     <skip />
-    <!-- no translation found for date_time_set (5777075614321087758) -->
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
     <skip />
-    <!-- no translation found for date_time_done (2507683751759308828) -->
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
     <skip />
-    <!-- no translation found for perms_new_perm_prefix (8257740710754301407) -->
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
     <skip />
-    <!-- no translation found for perms_description_app (5139836143293299417) -->
-    <skip />
-    <!-- no translation found for no_permissions (7283357728219338112) -->
-    <skip />
-    <!-- no translation found for perm_costs_money (4902470324142151116) -->
-    <skip />
-    <!-- no translation found for dlg_ok (7376953167039865701) -->
-    <skip />
-    <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
-    <skip />
-    <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
-    <skip />
-    <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
-    <skip />
-    <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
-    <skip />
-    <!-- no translation found for usb_accessory_notification_title (7848236974087653666) -->
-    <skip />
-    <!-- no translation found for usb_notification_message (7347368030849048437) -->
-    <skip />
-    <!-- no translation found for adb_active_notification_title (6729044778949189918) -->
-    <skip />
-    <!-- no translation found for adb_active_notification_message (1016654627626476142) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_title (3116061729914615290) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_message (1310517845557771773) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_accept (8203856129078669677) -->
-    <skip />
-    <!-- no translation found for share_remote_bugreport_notification_decline (6337969352057443969) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_title (2785600634417078622) -->
-    <skip />
-    <!-- no translation found for remote_bugreport_progress_notification_message_can_cancel (5743435483005099451) -->
-    <skip />
-    <!-- no translation found for select_input_method (8547250819326693584) -->
-    <skip />
-    <!-- no translation found for configure_input_methods (4769971288371946846) -->
-    <skip />
-    <!-- no translation found for show_ime (2506087537466597099) -->
-    <skip />
-    <!-- no translation found for hardware (194658061510127999) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
-    <skip />
-    <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
-    <skip />
-    <!-- no translation found for fast_scroll_alphabet (5433275485499039199) -->
-    <skip />
-    <!-- no translation found for fast_scroll_numeric_alphabet (4030170524595123610) -->
-    <skip />
-    <!-- no translation found for candidates_style (4333913089637062257) -->
-    <skip />
-    <!-- no translation found for ext_media_checking_notification_title (5734005953288045806) -->
-    <skip />
-    <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
-    <skip />
-    <!-- no translation found for ext_media_new_notification_message (7589986898808506239) -->
-    <skip />
-    <!-- no translation found for ext_media_ready_notification_message (4083398150380114462) -->
-    <skip />
-    <!-- no translation found for ext_media_unmountable_notification_title (8295123366236989588) -->
-    <skip />
-    <!-- no translation found for ext_media_unmountable_notification_message (1586311304430052169) -->
-    <skip />
-    <!-- no translation found for ext_media_unsupported_notification_title (3797642322958803257) -->
-    <skip />
-    <!-- no translation found for ext_media_unsupported_notification_message (8789610369456474891) -->
-    <skip />
-    <!-- no translation found for ext_media_badremoval_notification_title (3206248947375505416) -->
-    <skip />
-    <!-- no translation found for ext_media_badremoval_notification_message (380176703346946313) -->
-    <skip />
-    <!-- no translation found for ext_media_nomedia_notification_title (1704840188641749091) -->
-    <skip />
-    <!-- no translation found for ext_media_nomedia_notification_message (6471542972147056586) -->
-    <skip />
-    <!-- no translation found for ext_media_unmounting_notification_title (640674168454809372) -->
-    <skip />
-    <!-- no translation found for ext_media_unmounting_notification_message (4182843895023357756) -->
-    <skip />
-    <!-- no translation found for ext_media_init_action (7952885510091978278) -->
-    <skip />
-    <!-- no translation found for ext_media_unmount_action (1121883233103278199) -->
-    <skip />
-    <!-- no translation found for ext_media_browse_action (8322172381028546087) -->
-    <skip />
-    <!-- no translation found for ext_media_missing_title (620980315821543904) -->
-    <skip />
-    <!-- no translation found for ext_media_missing_message (5761133583368750174) -->
-    <skip />
-    <!-- no translation found for ext_media_move_specific_title (1471100343872375842) -->
-    <skip />
-    <!-- no translation found for ext_media_move_title (1022809140035962662) -->
-    <skip />
-    <!-- no translation found for ext_media_move_success_title (8575300932957954671) -->
-    <skip />
-    <!-- no translation found for ext_media_move_success_message (4199002148206265426) -->
-    <skip />
-    <!-- no translation found for ext_media_move_failure_title (7613189040358789908) -->
-    <skip />
-    <!-- no translation found for ext_media_move_failure_message (1978096440816403360) -->
-    <skip />
-    <!-- no translation found for ext_media_status_removed (6576172423185918739) -->
-    <skip />
-    <!-- no translation found for ext_media_status_unmounted (2551560878416417752) -->
-    <skip />
-    <!-- no translation found for ext_media_status_checking (6193921557423194949) -->
-    <skip />
-    <!-- no translation found for ext_media_status_mounted (7253821726503179202) -->
-    <skip />
-    <!-- no translation found for ext_media_status_mounted_ro (8020978752406021015) -->
-    <skip />
-    <!-- no translation found for ext_media_status_bad_removal (8395398567890329422) -->
-    <skip />
-    <!-- no translation found for ext_media_status_unmountable (805594039236667894) -->
-    <skip />
-    <!-- no translation found for ext_media_status_unsupported (4691436711745681828) -->
-    <skip />
-    <!-- no translation found for ext_media_status_ejecting (5463887263101234174) -->
-    <skip />
-    <!-- no translation found for ext_media_status_formatting (1085079556538644861) -->
-    <skip />
-    <!-- no translation found for ext_media_status_missing (5638633895221670766) -->
-    <skip />
-    <!-- no translation found for activity_list_empty (1675388330786841066) -->
-    <skip />
-    <!-- no translation found for permlab_route_media_output (6243022988998972085) -->
-    <skip />
-    <!-- no translation found for permdesc_route_media_output (4932818749547244346) -->
-    <skip />
-    <!-- no translation found for permlab_readInstallSessions (3713753067455750349) -->
-    <skip />
-    <!-- no translation found for permdesc_readInstallSessions (2049771699626019849) -->
-    <skip />
-    <!-- no translation found for permlab_requestInstallPackages (5782013576218172577) -->
-    <skip />
-    <!-- no translation found for permdesc_requestInstallPackages (5740101072486783082) -->
-    <skip />
-    <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) -->
-    <skip />
-    <!-- no translation found for gadget_host_error_inflating (4882004314906466162) -->
-    <skip />
-    <!-- no translation found for ime_action_go (8320845651737369027) -->
-    <skip />
-    <!-- no translation found for ime_action_search (658110271822807811) -->
-    <skip />
-    <!-- no translation found for ime_action_send (2316166556349314424) -->
-    <skip />
-    <!-- no translation found for ime_action_next (3138843904009813834) -->
-    <skip />
-    <!-- no translation found for ime_action_done (8971516117910934605) -->
-    <skip />
-    <!-- no translation found for ime_action_previous (1443550039250105948) -->
-    <skip />
-    <!-- no translation found for ime_action_default (2840921885558045721) -->
-    <skip />
-    <!-- no translation found for dial_number_using (5789176425167573586) -->
-    <skip />
-    <!-- no translation found for create_contact_using (4947405226788104538) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_header (2106103817937859662) -->
-    <skip />
-    <!-- no translation found for grant_credentials_permission_message_footer (3125211343379376561) -->
-    <skip />
-    <!-- no translation found for grant_permissions_header_text (6874497408201826708) -->
-    <skip />
-    <!-- no translation found for allow (7225948811296386551) -->
-    <skip />
-    <!-- no translation found for deny (2081879885755434506) -->
-    <skip />
-    <!-- no translation found for permission_request_notification_title (6486759795926237907) -->
-    <skip />
-    <!-- no translation found for permission_request_notification_with_subtitle (8530393139639560189) -->
-    <skip />
-    <!-- no translation found for forward_intent_to_owner (1207197447013960896) -->
-    <skip />
-    <!-- no translation found for forward_intent_to_work (621480743856004612) -->
-    <skip />
-    <!-- no translation found for input_method_binding_label (1283557179944992649) -->
-    <skip />
-    <!-- no translation found for sync_binding_label (3687969138375092423) -->
-    <skip />
-    <!-- no translation found for accessibility_binding_label (4148120742096474641) -->
-    <skip />
-    <!-- no translation found for wallpaper_binding_label (1240087844304687662) -->
-    <skip />
-    <!-- no translation found for chooser_wallpaper (7873476199295190279) -->
-    <skip />
-    <!-- no translation found for notification_listener_binding_label (2014162835481906429) -->
-    <skip />
-    <!-- no translation found for condition_provider_service_binding_label (1321343352906524564) -->
-    <skip />
-    <!-- no translation found for notification_assistant_binding_label (909456055569102952) -->
-    <skip />
-    <!-- no translation found for vpn_title (19615213552042827) -->
-    <skip />
-    <!-- no translation found for vpn_title_long (6400714798049252294) -->
-    <skip />
-    <!-- no translation found for vpn_text (3011306607126450322) -->
-    <skip />
-    <!-- no translation found for vpn_text_long (6407351006249174473) -->
-    <skip />
-    <!-- no translation found for vpn_lockdown_connecting (6443438964440960745) -->
-    <skip />
-    <!-- no translation found for vpn_lockdown_connected (8202679674819213931) -->
-    <skip />
-    <!-- no translation found for vpn_lockdown_error (6009249814034708175) -->
-    <skip />
-    <!-- no translation found for vpn_lockdown_config (6415899150671537970) -->
-    <skip />
-    <!-- no translation found for upload_file (2897957172366730416) -->
-    <skip />
-    <!-- no translation found for no_file_chosen (6363648562170759465) -->
-    <skip />
-    <!-- no translation found for reset (2448168080964209908) -->
-    <skip />
-    <!-- no translation found for submit (1602335572089911941) -->
-    <skip />
-    <!-- no translation found for car_mode_disable_notification_title (3164768212003864316) -->
-    <skip />
-    <!-- no translation found for car_mode_disable_notification_message (8035230537563503262) -->
-    <skip />
-    <!-- no translation found for tethered_notification_title (3146694234398202601) -->
-    <skip />
-    <!-- no translation found for tethered_notification_message (6857031760103062982) -->
-    <skip />
-    <!-- no translation found for back_button_label (2300470004503343439) -->
-    <skip />
-    <!-- no translation found for next_button_label (1080555104677992408) -->
-    <skip />
-    <!-- no translation found for skip_button_label (1275362299471631819) -->
-    <skip />
-    <!-- no translation found for no_matches (8129421908915840737) -->
-    <skip />
-    <!-- no translation found for find_on_page (1946799233822820384) -->
-    <skip />
-    <!-- no translation found for matches_found (1210884353962081884) -->
-    <!-- no translation found for action_mode_done (7217581640461922289) -->
-    <skip />
-    <!-- no translation found for progress_erasing (4521573321524340058) -->
-    <skip />
-    <!-- no translation found for progress_erasing (6596988875507043042) -->
-    <skip />
-    <!-- no translation found for share (1778686618230011964) -->
-    <skip />
-    <!-- no translation found for find (4808270900322985960) -->
-    <skip />
-    <!-- no translation found for websearch (4337157977400211589) -->
-    <skip />
-    <!-- no translation found for find_next (5742124618942193978) -->
-    <skip />
-    <!-- no translation found for find_previous (2196723669388360506) -->
-    <skip />
-    <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
-    <skip />
-    <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
-    <skip />
-    <!-- no translation found for gpsNotifMessage (1374718023224000702) -->
-    <skip />
-    <!-- no translation found for gpsVerifYes (2346566072867213563) -->
-    <skip />
-    <!-- no translation found for gpsVerifNo (1146564937346454865) -->
-    <skip />
-    <!-- no translation found for sync_too_many_deletes (5296321850662746890) -->
-    <skip />
-    <!-- no translation found for sync_too_many_deletes_desc (496551671008694245) -->
-    <skip />
-    <!-- no translation found for sync_really_delete (2572600103122596243) -->
-    <skip />
-    <!-- no translation found for sync_undo_deletes (2941317360600338602) -->
-    <skip />
-    <!-- no translation found for sync_do_nothing (3743764740430821845) -->
-    <skip />
-    <!-- no translation found for choose_account_label (5655203089746423927) -->
-    <skip />
-    <!-- no translation found for add_account_label (2935267344849993553) -->
-    <skip />
-    <!-- no translation found for add_account_button_label (3611982894853435874) -->
-    <skip />
-    <!-- no translation found for number_picker_increment_button (2412072272832284313) -->
-    <skip />
-    <!-- no translation found for number_picker_decrement_button (476050778386779067) -->
-    <skip />
-    <!-- no translation found for number_picker_increment_scroll_mode (3073101067441638428) -->
-    <skip />
-    <!-- no translation found for number_picker_increment_scroll_action (9101473045891835490) -->
-    <skip />
-    <!-- no translation found for time_picker_increment_minute_button (8865885114028614321) -->
-    <skip />
-    <!-- no translation found for time_picker_decrement_minute_button (6246834937080684791) -->
-    <skip />
-    <!-- no translation found for time_picker_increment_hour_button (3652056055810223139) -->
-    <skip />
-    <!-- no translation found for time_picker_decrement_hour_button (1377479863429214792) -->
-    <skip />
-    <!-- no translation found for time_picker_increment_set_pm_button (4147590696151230863) -->
-    <skip />
-    <!-- no translation found for time_picker_decrement_set_am_button (8302140353539486752) -->
-    <skip />
-    <!-- no translation found for date_picker_increment_month_button (5369998479067934110) -->
-    <skip />
-    <!-- no translation found for date_picker_decrement_month_button (1832698995541726019) -->
-    <skip />
-    <!-- no translation found for date_picker_increment_day_button (7130465412308173903) -->
-    <skip />
-    <!-- no translation found for date_picker_decrement_day_button (4131881521818750031) -->
-    <skip />
-    <!-- no translation found for date_picker_increment_year_button (6318697384310808899) -->
-    <skip />
-    <!-- no translation found for date_picker_decrement_year_button (4482021813491121717) -->
-    <skip />
-    <!-- no translation found for date_picker_prev_month_button (2858244643992056505) -->
-    <skip />
-    <!-- no translation found for date_picker_next_month_button (5559507736887605055) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_alt (4856868820040051939) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_cancel (1203984017245783244) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_delete (3337914833206635744) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_done (1992571118466679775) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_mode_change (4547387741906537519) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_shift (2270748814315147690) -->
-    <skip />
-    <!-- no translation found for keyboardview_keycode_enter (2985864015076059467) -->
-    <skip />
-    <!-- no translation found for activitychooserview_choose_application (2125168057199941199) -->
-    <skip />
-    <!-- no translation found for activitychooserview_choose_application_error (8624618365481126668) -->
-    <skip />
-    <!-- no translation found for shareactionprovider_share_with (806688056141131819) -->
-    <skip />
-    <!-- no translation found for shareactionprovider_share_with_application (5627411384638389738) -->
-    <skip />
-    <!-- no translation found for content_description_sliding_handle (415975056159262248) -->
-    <skip />
-    <!-- no translation found for description_target_unlock_tablet (3833195335629795055) -->
-    <skip />
-    <!-- no translation found for keyboard_headset_required_to_hear_password (7011927352267668657) -->
-    <skip />
-    <!-- no translation found for keyboard_password_character_no_headset (2859873770886153678) -->
-    <skip />
-    <!-- no translation found for action_bar_home_description (5293600496601490216) -->
-    <skip />
-    <!-- no translation found for action_bar_up_description (2237496562952152589) -->
-    <skip />
-    <!-- no translation found for action_menu_overflow_description (2295659037509008453) -->
-    <skip />
-    <!-- no translation found for action_bar_home_description_format (7965984360903693903) -->
-    <skip />
-    <!-- no translation found for action_bar_home_subtitle_description_format (6985546530471780727) -->
-    <skip />
-    <!-- no translation found for storage_internal (4891916833657929263) -->
-    <skip />
-    <!-- no translation found for storage_sd_card (3282948861378286745) -->
-    <skip />
-    <!-- no translation found for storage_sd_card_label (6347111320774379257) -->
-    <skip />
-    <!-- no translation found for storage_usb_drive (6261899683292244209) -->
-    <skip />
-    <!-- no translation found for storage_usb_drive_label (4501418548927759953) -->
-    <skip />
-    <!-- no translation found for storage_usb (3017954059538517278) -->
-    <skip />
-    <!-- no translation found for extract_edit_menu_button (8940478730496610137) -->
-    <skip />
-    <!-- no translation found for data_usage_warning_title (1955638862122232342) -->
-    <skip />
-    <!-- no translation found for data_usage_warning_body (2814673551471969954) -->
-    <skip />
-    <!-- no translation found for data_usage_3g_limit_title (4361523876818447683) -->
-    <skip />
-    <!-- no translation found for data_usage_4g_limit_title (4609566827219442376) -->
-    <skip />
-    <!-- no translation found for data_usage_mobile_limit_title (557158376602636112) -->
-    <skip />
-    <!-- no translation found for data_usage_wifi_limit_title (5803363779034792676) -->
-    <skip />
-    <!-- no translation found for data_usage_limit_body (291731708279614081) -->
-    <skip />
-    <!-- no translation found for data_usage_3g_limit_snoozed_title (7026739121138005231) -->
-    <skip />
-    <!-- no translation found for data_usage_4g_limit_snoozed_title (1106562779311209039) -->
-    <skip />
-    <!-- no translation found for data_usage_mobile_limit_snoozed_title (4941346653729943789) -->
-    <skip />
-    <!-- no translation found for data_usage_wifi_limit_snoozed_title (8743856006384825974) -->
-    <skip />
-    <!-- no translation found for data_usage_limit_snoozed_body (7035490278298441767) -->
-    <skip />
-    <!-- no translation found for data_usage_restricted_title (5965157361036321914) -->
-    <skip />
-    <!-- no translation found for data_usage_restricted_body (6741521330997452990) -->
-    <skip />
-    <!-- no translation found for ssl_certificate (6510040486049237639) -->
-    <skip />
-    <!-- no translation found for ssl_certificate_is_valid (6825263250774569373) -->
-    <skip />
-    <!-- no translation found for issued_to (454239480274921032) -->
-    <skip />
-    <!-- no translation found for common_name (2233209299434172646) -->
-    <skip />
-    <!-- no translation found for org_name (6973561190762085236) -->
-    <skip />
-    <!-- no translation found for org_unit (7265981890422070383) -->
-    <skip />
-    <!-- no translation found for issued_by (2647584988057481566) -->
-    <skip />
-    <!-- no translation found for validity_period (8818886137545983110) -->
-    <skip />
-    <!-- no translation found for issued_on (5895017404361397232) -->
-    <skip />
-    <!-- no translation found for expires_on (3676242949915959821) -->
-    <skip />
-    <!-- no translation found for serial_number (758814067660862493) -->
-    <skip />
-    <!-- no translation found for fingerprints (4516019619850763049) -->
-    <skip />
-    <!-- no translation found for sha256_fingerprint (4391271286477279263) -->
-    <skip />
-    <!-- no translation found for sha1_fingerprint (7930330235269404581) -->
-    <skip />
-    <!-- no translation found for activity_chooser_view_see_all (4292569383976636200) -->
-    <skip />
-    <!-- no translation found for activity_chooser_view_dialog_title_default (4710013864974040615) -->
-    <skip />
-    <!-- no translation found for share_action_provider_share_with (5247684435979149216) -->
-    <skip />
-    <!-- no translation found for sending (3245653681008218030) -->
-    <skip />
-    <!-- no translation found for launchBrowserDefault (2057951947297614725) -->
-    <skip />
-    <!-- no translation found for SetupCallDefault (5834948469253758575) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
-    <skip />
-    <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
-    <skip />
-    <!-- no translation found for activity_resolver_work_profiles_support (185598180676883455) -->
-    <skip />
-    <!-- no translation found for default_audio_route_name (4617053898167127471) -->
-    <skip />
-    <!-- no translation found for default_audio_route_name (9158088547603019321) -->
-    <skip />
-    <!-- no translation found for default_audio_route_name (4239291273420140123) -->
-    <skip />
-    <!-- no translation found for default_audio_route_name_headphones (8119971843803439110) -->
-    <skip />
-    <!-- no translation found for default_audio_route_name_dock_speakers (6240602982276591864) -->
-    <skip />
-    <!-- no translation found for default_media_route_name_hdmi (2450970399023478055) -->
-    <skip />
-    <!-- no translation found for default_audio_route_category_name (3722811174003886946) -->
-    <skip />
-    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
-    <skip />
-    <!-- no translation found for wireless_display_route_description (9070346425023979651) -->
-    <skip />
-    <!-- no translation found for media_route_button_content_description (591703006349356016) -->
-    <skip />
-    <!-- no translation found for media_route_chooser_title (1751618554539087622) -->
-    <skip />
-    <!-- no translation found for media_route_chooser_title_for_remote_display (3395541745872017583) -->
-    <skip />
-    <!-- no translation found for media_route_chooser_searching (4776236202610828706) -->
-    <skip />
-    <!-- no translation found for media_route_chooser_extended_settings (87015534236701604) -->
-    <skip />
-    <!-- no translation found for media_route_controller_disconnect (8966120286374158649) -->
-    <skip />
-    <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
-    <skip />
-    <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
-    <skip />
-    <!-- no translation found for media_route_status_available (6983258067194649391) -->
-    <skip />
-    <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
-    <skip />
-    <!-- no translation found for media_route_status_in_use (4533786031090198063) -->
-    <skip />
-    <!-- no translation found for display_manager_built_in_display_name (2583134294292563941) -->
-    <skip />
-    <!-- no translation found for display_manager_hdmi_display_name (1555264559227470109) -->
-    <skip />
-    <!-- no translation found for display_manager_overlay_display_name (5142365982271620716) -->
-    <skip />
-    <!-- no translation found for display_manager_overlay_display_title (652124517672257172) -->
-    <skip />
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
-    <!-- no translation found for kg_forgot_pattern_button_text (8852021467868220608) -->
-    <skip />
-    <!-- no translation found for kg_wrong_pattern (1850806070801358830) -->
-    <skip />
-    <!-- no translation found for kg_wrong_password (2333281762128113157) -->
-    <skip />
-    <!-- no translation found for kg_wrong_pin (1131306510833563801) -->
-    <skip />
-    <!-- no translation found for kg_too_many_failed_attempts_countdown (6358110221603297548) -->
-    <skip />
-    <!-- no translation found for kg_pattern_instructions (398978611683075868) -->
-    <skip />
-    <!-- no translation found for kg_sim_pin_instructions (2319508550934557331) -->
-    <skip />
-    <!-- no translation found for kg_pin_instructions (2377242233495111557) -->
-    <skip />
-    <!-- no translation found for kg_password_instructions (5753646556186936819) -->
-    <skip />
-    <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
-    <skip />
-    <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
-    <skip />
-    <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
-    <skip />
-    <!-- no translation found for kg_sim_unlock_progress_dialog_message (8950398016976865762) -->
-    <skip />
-    <!-- no translation found for kg_password_wrong_pin_code (1139324887413846912) -->
-    <skip />
-    <!-- no translation found for kg_invalid_sim_pin_hint (8795159358110620001) -->
-    <skip />
-    <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) -->
-    <skip />
-    <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
-    <skip />
-    <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
-    <skip />
-    <!-- no translation found for kg_login_too_many_attempts (6486842094005698475) -->
-    <skip />
-    <!-- no translation found for kg_login_instructions (1100551261265506448) -->
-    <skip />
-    <!-- no translation found for kg_login_username_hint (5718534272070920364) -->
-    <skip />
-    <!-- no translation found for kg_login_password_hint (9057289103827298549) -->
-    <skip />
-    <!-- no translation found for kg_login_submit_button (5355904582674054702) -->
-    <skip />
-    <!-- no translation found for kg_login_invalid_input (5754664119319872197) -->
-    <skip />
-    <!-- no translation found for kg_login_account_recovery_hint (5690709132841752974) -->
-    <skip />
-    <!-- no translation found for kg_login_checking_password (1052685197710252395) -->
-    <skip />
-    <!-- no translation found for kg_too_many_failed_pin_attempts_dialog_message (8276745642049502550) -->
-    <skip />
-    <!-- no translation found for kg_too_many_failed_password_attempts_dialog_message (7813713389422226531) -->
-    <skip />
-    <!-- no translation found for kg_too_many_failed_pattern_attempts_dialog_message (74089475965050805) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_wipe (1575557200627128949) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_wipe (5621231220154419413) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_wipe (4051015943038199910) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_now_wiping (2072996269148483637) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_now_wiping (4987878286750741463) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_now_wiping (4817627474419471518) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_login (3253575572118914370) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_login (4224651132862313471) -->
-    <skip />
-    <!-- no translation found for kg_failed_attempts_almost_at_login (1437638152015574839) -->
-    <skip />
-    <!-- no translation found for kg_text_message_separator (4160700433287233771) -->
-    <skip />
-    <!-- no translation found for kg_reordering_delete_drop_target_text (7899202978204438708) -->
-    <skip />
-    <!-- no translation found for safe_media_volume_warning (2276318909314492312) -->
-    <skip />
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
-    <!-- no translation found for accessibility_enabled (1381972048564547685) -->
-    <skip />
-    <!-- no translation found for enable_accessibility_canceled (3833923257966635673) -->
-    <skip />
-    <!-- no translation found for user_switched (3768006783166984410) -->
-    <skip />
-    <!-- no translation found for user_switching_message (2871009331809089783) -->
-    <skip />
-    <!-- no translation found for user_logging_out_message (8939524935808875155) -->
-    <skip />
-    <!-- no translation found for owner_name (2716755460376028154) -->
-    <!-- no translation found for owner_name (3879126011135546571) -->
-    <skip />
-    <!-- no translation found for error_message_title (4510373083082500195) -->
-    <skip />
-    <!-- no translation found for error_message_change_not_allowed (1347282344200417578) -->
-    <skip />
-    <!-- no translation found for app_not_found (3429141853498927379) -->
-    <skip />
-    <!-- no translation found for revoke (5404479185228271586) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a0 (1994474252931294172) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a1 (3333060421529791786) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a2 (3097535991925798280) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a3 (3023213259314236123) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a4 (231745325296873764) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a5 (3484327407340865411) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a6 (4861908487129577530) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a7 (5890208588072936130) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a8 (4319425041085816612) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a9 (4882220529506432008) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a10 (2382866026365359391) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b0 (3651827147402009675) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b1 (6072859628278739957) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b2 (1348731852150380378) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b3 (2612510181259261379) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b4 (695151378838115434) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b5 (4863754285582212487) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b6 (5305816292139647241) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b7 (531673542602786624) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b8 (9164474595708850034) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b9 (282102976764774160) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b10 (4517141714407898976) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c0 (3103521357901591100) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c1 (1231954105985048595) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c2 (927702816980087462) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c3 (835154173518304159) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c4 (5095951985108194011) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c5 (1985397450332305739) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c6 (8147421924174693013) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c7 (8993994925276122950) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c8 (6871178104139598957) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c9 (7983532635227561362) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c10 (5040764293406765584) -->
-    <skip />
-    <!-- no translation found for mediasize_na_letter (2841414839888344296) -->
-    <skip />
-    <!-- no translation found for mediasize_na_gvrnmt_letter (5295836838862962809) -->
-    <skip />
-    <!-- no translation found for mediasize_na_legal (8621364037680465666) -->
-    <skip />
-    <!-- no translation found for mediasize_na_junior_legal (3309324162155085904) -->
-    <skip />
-    <!-- no translation found for mediasize_na_ledger (5567030340509075333) -->
-    <skip />
-    <!-- no translation found for mediasize_na_tabloid (4571735038501661757) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_3x5 (5182901917818625126) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_4x6 (7687620625422312396) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_5x8 (8834215284646872800) -->
-    <skip />
-    <!-- no translation found for mediasize_na_monarch (213639906956550754) -->
-    <skip />
-    <!-- no translation found for mediasize_na_quarto (835778493593023223) -->
-    <skip />
-    <!-- no translation found for mediasize_na_foolscap (1573911237983677138) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_roc_8k (3626855847189438896) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_roc_16k (9182191577022943355) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_1 (4793232644980170500) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_2 (5404109730975720670) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_3 (1335092253339363526) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_4 (9167997800486569834) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_5 (845875168823541497) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_6 (3220325667692648789) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_7 (1776792138507038527) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_8 (1417176642687456692) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_9 (4785983473123798365) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_10 (7847982299391851899) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_16k (262793383539980677) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_pa_kai (5256815579447959814) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_dai_pa_kai (7336412963441354407) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_jurro_ku_kai (6324465444100490742) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b10 (1787262845627694376) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b9 (3336035783663287470) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b8 (6195398299104345731) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b7 (1674621886902828884) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b6 (4170576286062657435) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b5 (4899297958100032533) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b4 (4213158129126666847) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b3 (8513715307410310696) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b2 (4777690211897131190) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b1 (4608142385457034603) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b0 (7587108366572243991) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_exec (5244075432263649068) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou4 (4941652015032631361) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou3 (6387319169263957010) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou2 (1299112025415343982) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_hagaki (8070115620644254565) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_oufuku (6049065587307896564) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_kahu (6872696027560065173) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_kaku2 (2359077233775455405) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_you4 (2091777168747058008) -->
-    <skip />
-    <!-- no translation found for mediasize_unknown_portrait (3088043641616409762) -->
-    <skip />
-    <!-- no translation found for mediasize_unknown_landscape (4876995327029361552) -->
-    <skip />
-    <!-- no translation found for write_fail_reason_cancelled (7091258378121627624) -->
-    <skip />
-    <!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
-    <skip />
-    <!-- no translation found for reason_unknown (6048913880184628119) -->
-    <skip />
-    <!-- no translation found for reason_service_unavailable (7824008732243903268) -->
-    <skip />
-    <!-- no translation found for print_service_installed_title (2246317169444081628) -->
-    <skip />
-    <!-- no translation found for print_service_installed_message (5897362931070459152) -->
-    <skip />
-    <!-- no translation found for restr_pin_enter_admin_pin (783643731895143970) -->
-    <skip />
-    <!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
-    <skip />
-    <!-- no translation found for restr_pin_incorrect (8571512003955077924) -->
-    <skip />
-    <!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
-    <skip />
-    <!-- no translation found for restr_pin_enter_new_pin (5959606691619959184) -->
-    <skip />
-    <!-- no translation found for restr_pin_confirm_pin (8501523829633146239) -->
-    <skip />
-    <!-- no translation found for restr_pin_create_pin (8017600000263450337) -->
-    <skip />
-    <!-- no translation found for restr_pin_error_doesnt_match (2224214190906994548) -->
-    <skip />
-    <!-- no translation found for restr_pin_error_too_short (8173982756265777792) -->
-    <skip />
-    <!-- no translation found for restr_pin_countdown (9061246974881224688) -->
-    <!-- no translation found for restr_pin_try_later (973144472490532377) -->
-    <skip />
-    <!-- no translation found for immersive_cling_title (8394201622932303336) -->
-    <skip />
-    <!-- no translation found for immersive_cling_description (3482371193207536040) -->
-    <skip />
-    <!-- no translation found for immersive_cling_positive (5016839404568297683) -->
-    <skip />
-    <!-- no translation found for done_label (2093726099505892398) -->
-    <skip />
-    <!-- no translation found for hour_picker_description (6698199186859736512) -->
-    <skip />
-    <!-- no translation found for minute_picker_description (8606010966873791190) -->
-    <skip />
-    <!-- no translation found for select_hours (6043079511766008245) -->
-    <skip />
-    <!-- no translation found for select_minutes (3974345615920336087) -->
-    <skip />
-    <!-- no translation found for select_day (7774759604701773332) -->
-    <skip />
-    <!-- no translation found for select_year (7952052866994196170) -->
-    <skip />
-    <!-- no translation found for deleted_key (7659477886625566590) -->
-    <skip />
-    <!-- no translation found for managed_profile_label_badge (2355652472854327647) -->
-    <skip />
-    <!-- no translation found for lock_to_app_toast (7570091317001980053) -->
-    <skip />
-    <!-- no translation found for lock_to_app_toast_accessible (8239120109365070664) -->
-    <skip />
-    <!-- no translation found for lock_to_app_toast_locked (9125176335701699164) -->
-    <skip />
-    <!-- no translation found for lock_to_app_start (6643342070839862795) -->
-    <skip />
-    <!-- no translation found for lock_to_app_exit (8598219838213787430) -->
-    <skip />
-    <!-- no translation found for lock_to_app_unlock_pin (2552556656504331634) -->
-    <skip />
-    <!-- no translation found for lock_to_app_unlock_pattern (4182192144797225137) -->
-    <skip />
-    <!-- no translation found for lock_to_app_unlock_password (6380979775916974414) -->
-    <skip />
+    <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIHVATI"</string>
+    <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODBACI"</string>
+    <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string>
+    <string name="configure_input_methods" msgid="4769971288371946846">"Odaberite tastature"</string>
+    <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
+    <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tastaturu"</string>
+    <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Odaberite raspored tastature"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Dodirnite za odabir rasporeda tastature."</string>
+    <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
+    <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema se <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Provjera grešaka"</string>
+    <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novi uređaj <xliff:g id="NAME">%s</xliff:g> je otkriven"</string>
+    <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Za prebacivanje slika i medijskih fajlova"</string>
+    <string name="ext_media_unmountable_notification_title" msgid="8295123366236989588">"Uređaj <xliff:g id="NAME">%s</xliff:g> je oštećen"</string>
+    <string name="ext_media_unmountable_notification_message" msgid="1586311304430052169">"Uređaj <xliff:g id="NAME">%s</xliff:g> je oštećen. Dodirnite da ga popravite."</string>
+    <string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"Uređaj <xliff:g id="NAME">%s</xliff:g> nije podržan"</string>
+    <string name="ext_media_unsupported_notification_message" msgid="8789610369456474891">"Ovaj uređaj ne podržava uređaj <xliff:g id="NAME">%s</xliff:g>. Dodirnite da ga postavite u podržanom formatu."</string>
+    <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Neočekivano uklonjen uređaj <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_badremoval_notification_message" msgid="380176703346946313">"Isključite uređaj <xliff:g id="NAME">%s</xliff:g> prije uklanjanja da izbjegnete gubitak podataka"</string>
+    <string name="ext_media_nomedia_notification_title" msgid="1704840188641749091">"Uređaj <xliff:g id="NAME">%s</xliff:g> je uklonjen"</string>
+    <string name="ext_media_nomedia_notification_message" msgid="6471542972147056586">"Uređaj <xliff:g id="NAME">%s</xliff:g> je uklonjen, umetnite novi"</string>
+    <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Još uvijek se izbacuje <xliff:g id="NAME">%s</xliff:g>…"</string>
+    <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Ne uklanjajte"</string>
+    <string name="ext_media_init_action" msgid="7952885510091978278">"Postavi"</string>
+    <string name="ext_media_unmount_action" msgid="1121883233103278199">"Izbaci"</string>
+    <string name="ext_media_browse_action" msgid="8322172381028546087">"Istraži"</string>
+    <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> nedostaje"</string>
+    <string name="ext_media_missing_message" msgid="5761133583368750174">"Ponovo umetnite ovaj uređaj"</string>
+    <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Premješta se <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_move_title" msgid="1022809140035962662">"Premještanje podataka"</string>
+    <string name="ext_media_move_success_title" msgid="8575300932957954671">"Premještanje je završeno"</string>
+    <string name="ext_media_move_success_message" msgid="4199002148206265426">"Podaci su premješteni na uređaj <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Podaci se ne mogu premjestiti"</string>
+    <string name="ext_media_move_failure_message" msgid="1978096440816403360">"Podaci su ostali na prvobitnoj lokaciji"</string>
+    <string name="ext_media_status_removed" msgid="6576172423185918739">"Uređaj je uklonjen"</string>
+    <string name="ext_media_status_unmounted" msgid="2551560878416417752">"Uređaj je izbačen"</string>
+    <string name="ext_media_status_checking" msgid="6193921557423194949">"Provjerava se..."</string>
+    <string name="ext_media_status_mounted" msgid="7253821726503179202">"Uređaj je spreman"</string>
+    <string name="ext_media_status_mounted_ro" msgid="8020978752406021015">"Samo za čitanje"</string>
+    <string name="ext_media_status_bad_removal" msgid="8395398567890329422">"Uređaj je uklonjen na nebezbjedan način"</string>
+    <string name="ext_media_status_unmountable" msgid="805594039236667894">"Uređaj je oštećen"</string>
+    <string name="ext_media_status_unsupported" msgid="4691436711745681828">"Uređaj nije podržan"</string>
+    <string name="ext_media_status_ejecting" msgid="5463887263101234174">"Izbacuje se..."</string>
+    <string name="ext_media_status_formatting" msgid="1085079556538644861">"Formatira se..."</string>
+    <string name="ext_media_status_missing" msgid="5638633895221670766">"Uređaj nije ubačen"</string>
+    <string name="activity_list_empty" msgid="1675388330786841066">"Nije pronađena nijedna odgovarajuća aktivnost."</string>
+    <string name="permlab_route_media_output" msgid="6243022988998972085">"usmjeravanje izlaza za medijske fajlove"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Omogućava aplikaciji usmjeravanje izlaza sa medija na druge vanjske uređaje."</string>
+    <string name="permlab_readInstallSessions" msgid="3713753067455750349">"čitanje sesija instaliranja"</string>
+    <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Dozvoljava aplikaciji da čita sesije instalacija. Ovim se aplikaciji omogućava da vidi detalje o aktivnim instalacijama paketa."</string>
+    <string name="permlab_requestInstallPackages" msgid="5782013576218172577">"zahtijevanje paketa za instaliranje"</string>
+    <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Omogućava aplikaciji da zahtijeva instalaciju paket ā."</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Dodirnite dvaput za kontrolu uvećavanja"</string>
+    <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Dodavanje vidžeta nije uspjelo."</string>
+    <string name="ime_action_go" msgid="8320845651737369027">"Počni"</string>
+    <string name="ime_action_search" msgid="658110271822807811">"Traži"</string>
+    <string name="ime_action_send" msgid="2316166556349314424">"Poslati"</string>
+    <string name="ime_action_next" msgid="3138843904009813834">"Naprijed"</string>
+    <string name="ime_action_done" msgid="8971516117910934605">"Gotovo"</string>
+    <string name="ime_action_previous" msgid="1443550039250105948">"Naz."</string>
+    <string name="ime_action_default" msgid="2840921885558045721">"Izvrši"</string>
+    <string name="dial_number_using" msgid="5789176425167573586">"Biraj\nbroj <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="create_contact_using" msgid="4947405226788104538">"Napraviti kontakt\nkoristeći broj <xliff:g id="NUMBER">%s</xliff:g>"</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"Sljedeće aplikacije zahtijevaju dozvolu za pristup vašem računu, sada i u budućnosti."</string>
+    <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"Želite li dozvoliti taj zahtjev?"</string>
+    <string name="grant_permissions_header_text" msgid="6874497408201826708">"Zahtjev za pristup"</string>
+    <string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
+    <string name="deny" msgid="2081879885755434506">"Odbijte"</string>
+    <string name="permission_request_notification_title" msgid="6486759795926237907">"Upućen zahtjev za dozvolu"</string>
+    <string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"Upućen zahtjev za dozvolu\nza račun <xliff:g id="ACCOUNT">%s</xliff:g>."</string>
+    <string name="forward_intent_to_owner" msgid="1207197447013960896">"Aplikaciju koristite van poslovnog profila"</string>
+    <string name="forward_intent_to_work" msgid="621480743856004612">"Aplikaciju koristite u poslovnom profilu"</string>
+    <string name="input_method_binding_label" msgid="1283557179944992649">"Način unosa"</string>
+    <string name="sync_binding_label" msgid="3687969138375092423">"Sinhrona"</string>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Pristupačnost"</string>
+    <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pozadinska slika"</string>
+    <string name="chooser_wallpaper" msgid="7873476199295190279">"Promijenite pozadinsku sliku"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Usluga za praćenje obavještenja"</string>
+    <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Pružalac uslova"</string>
+    <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pomoćnik za obavještenja"</string>
+    <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string>
+    <string name="vpn_title_long" msgid="6400714798049252294">"Aplikacija <xliff:g id="APP">%s</xliff:g> je aktivirala VPN"</string>
+    <string name="vpn_text" msgid="3011306607126450322">"Dodirnite za upravljanje mrežom."</string>
+    <string name="vpn_text_long" msgid="6407351006249174473">"Uspostavljena veza sa <xliff:g id="SESSION">%s</xliff:g>. Dodirnite za upravljanje mrežom."</string>
+    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Povezivanje na uvijek aktivni VPN…"</string>
+    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Povezan na uvijek aktivni VPN"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"Greška u povezivanju na uvijek aktivni VPN"</string>
+    <string name="vpn_lockdown_config" msgid="6415899150671537970">"Dodirnite da konfigurirate"</string>
+    <string name="upload_file" msgid="2897957172366730416">"Odabir fajla"</string>
+    <string name="no_file_chosen" msgid="6363648562170759465">"Nije izabran nijedan fajl"</string>
+    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
+    <string name="submit" msgid="1602335572089911941">"Potvrdi"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Način rada u autu omogućen"</string>
+    <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Dodirnite kako biste izašli iz načina rada u autu."</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Uređaj dijeli vezu ili djeluje kao pristupna tačka"</string>
+    <string name="tethered_notification_message" msgid="6857031760103062982">"Dodirnite za postavljanje."</string>
+    <string name="back_button_label" msgid="2300470004503343439">"Nazad"</string>
+    <string name="next_button_label" msgid="1080555104677992408">"Naprijed"</string>
+    <string name="skip_button_label" msgid="1275362299471631819">"Preskoči"</string>
+    <string name="no_matches" msgid="8129421908915840737">"Nema podudaranja"</string>
+    <string name="find_on_page" msgid="1946799233822820384">"Pronađi na stranici"</string>
+    <plurals name="matches_found" formatted="false" msgid="1210884353962081884">
+      <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> od <xliff:g id="TOTAL">%d</xliff:g></item>
+      <item quantity="few"><xliff:g id="INDEX">%d</xliff:g> od <xliff:g id="TOTAL">%d</xliff:g></item>
+      <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> od <xliff:g id="TOTAL">%d</xliff:g></item>
+    </plurals>
+    <string name="action_mode_done" msgid="7217581640461922289">"Gotovo"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Brisanje USB pohrane..."</string>
+    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Brisanje SD kartice..."</string>
+    <string name="share" msgid="1778686618230011964">"Podijelite"</string>
+    <string name="find" msgid="4808270900322985960">"Pronađi"</string>
+    <string name="websearch" msgid="4337157977400211589">"Internet pretraga"</string>
+    <string name="find_next" msgid="5742124618942193978">"Nađi sljedeći"</string>
+    <string name="find_previous" msgid="2196723669388360506">"Nađi prethodni"</string>
+    <string name="gpsNotifTicker" msgid="5622683912616496172">"Korisnik <xliff:g id="NAME">%s</xliff:g> je poslao zahtjev za utvrđivanje lokacije"</string>
+    <string name="gpsNotifTitle" msgid="5446858717157416839">"Zahtjev za utvrđivanje lokacije"</string>
+    <string name="gpsNotifMessage" msgid="1374718023224000702">"Zahtjev uputio <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)"</string>
+    <string name="gpsVerifYes" msgid="2346566072867213563">"Da"</string>
+    <string name="gpsVerifNo" msgid="1146564937346454865">"Ne"</string>
+    <string name="sync_too_many_deletes" msgid="5296321850662746890">"Granica za brisanje prekoračena"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"Izbrisano je <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> stavki za <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>, račun <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g>. Šta želite uraditi?"</string>
+    <string name="sync_really_delete" msgid="2572600103122596243">"Obriši stavke"</string>
+    <string name="sync_undo_deletes" msgid="2941317360600338602">"Poništiti brisanje"</string>
+    <string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
+    <string name="choose_account_label" msgid="5655203089746423927">"Odaberite račun"</string>
+    <string name="add_account_label" msgid="2935267344849993553">"Dodajte račun"</string>
+    <string name="add_account_button_label" msgid="3611982894853435874">"Dodajte račun"</string>
+    <string name="number_picker_increment_button" msgid="2412072272832284313">"Povećaj"</string>
+    <string name="number_picker_decrement_button" msgid="476050778386779067">"Smanji"</string>
+    <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"Dodirnite <xliff:g id="VALUE">%s</xliff:g> i držite."</string>
+    <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Kliznite gore da povećate i dolje da smanjite."</string>
+    <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Povećaj minute"</string>
+    <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Smanji minute"</string>
+    <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Povećaj sate"</string>
+    <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Smanji sate"</string>
+    <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Postavi za poslijepodne (PM)"</string>
+    <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Postavi za prijepodne (AM)"</string>
+    <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Povećaj mjesece"</string>
+    <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Smanji mjesece"</string>
+    <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Povećaj dane"</string>
+    <string name="date_picker_decrement_day_button" msgid="4131881521818750031">"Smanji dane"</string>
+    <string name="date_picker_increment_year_button" msgid="6318697384310808899">"Povećaj godine"</string>
+    <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"Smanji godine"</string>
+    <string name="date_picker_prev_month_button" msgid="2858244643992056505">"Prethodni mjesec"</string>
+    <string name="date_picker_next_month_button" msgid="5559507736887605055">"Sljedeći mjesec"</string>
+    <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Prekini"</string>
+    <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Izbriši"</string>
+    <string name="keyboardview_keycode_done" msgid="1992571118466679775">"Gotovo"</string>
+    <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Promjena načina rada"</string>
+    <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
+    <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Potvrdi"</string>
+    <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Odaberite aplikaciju"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikacija <xliff:g id="APPLICATION_NAME">%s</xliff:g> se ne može pokrenuti."</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Podijeliti sa"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Podijeli koristeći aplikaciju <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="content_description_sliding_handle" msgid="415975056159262248">"Klizni regulator. Dodirnite &amp; držite."</string>
+    <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Prevucite za otključavanje ekrana."</string>
+    <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalice kako biste čuli dugmad prilikom kucanja lozinke."</string>
+    <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tačka."</string>
+    <string name="action_bar_home_description" msgid="5293600496601490216">"Vratite se na početnu stranicu"</string>
+    <string name="action_bar_up_description" msgid="2237496562952152589">"Navigirajte prema gore"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"Više opcija"</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">"Interna pohrana"</string>
+    <string name="storage_sd_card" msgid="3282948861378286745">"SD kartica"</string>
+    <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD kartica"</string>
+    <string name="storage_usb_drive" msgid="6261899683292244209">"USB disk"</string>
+    <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB disk"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
+    <string name="extract_edit_menu_button" msgid="8940478730496610137">"Uredi"</string>
+    <string name="data_usage_warning_title" msgid="1955638862122232342">"Upozorenje za prijenos podataka"</string>
+    <string name="data_usage_warning_body" msgid="2814673551471969954">"Podaci o korištenju i postavke"</string>
+    <string name="data_usage_3g_limit_title" msgid="4361523876818447683">"Dostignut limit za 2G-3G podatke"</string>
+    <string name="data_usage_4g_limit_title" msgid="4609566827219442376">"Dostignut limit za 4G podatke"</string>
+    <string name="data_usage_mobile_limit_title" msgid="557158376602636112">"Dostignut limit mob. podataka"</string>
+    <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Dostignut limit Wi-Fi podataka"</string>
+    <string name="data_usage_limit_body" msgid="291731708279614081">"Podaci pauz. za ostatak ciklusa"</string>
+    <string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"Premašeni 2G-3G podaci"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"Premašeni 4G podaci"</string>
+    <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Limit mob. podataka prekoračen"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Premašeno Wi-Fi ograničenje"</string>
+    <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> preko navedenog ograničenja."</string>
+    <string name="data_usage_restricted_title" msgid="5965157361036321914">"Pozadinski podaci su ograničeni"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Dodirnuti za uklanjanje ogran."</string>
+    <string name="ssl_certificate" msgid="6510040486049237639">"Sigurnosni certifikat"</string>
+    <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ovaj certifikat je važeći."</string>
+    <string name="issued_to" msgid="454239480274921032">"Primalac:"</string>
+    <string name="common_name" msgid="2233209299434172646">"Ime domene:"</string>
+    <string name="org_name" msgid="6973561190762085236">"Organizacija:"</string>
+    <string name="org_unit" msgid="7265981890422070383">"Organizaciona jedinica:"</string>
+    <string name="issued_by" msgid="2647584988057481566">"Izdao:"</string>
+    <string name="validity_period" msgid="8818886137545983110">"Valjanost:"</string>
+    <string name="issued_on" msgid="5895017404361397232">"Datum izdavanja:"</string>
+    <string name="expires_on" msgid="3676242949915959821">"Ističe:"</string>
+    <string name="serial_number" msgid="758814067660862493">"Serijski broj:"</string>
+    <string name="fingerprints" msgid="4516019619850763049">"Otisci prstiju:"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 otisak prsta:"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 otisak prsta:"</string>
+    <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Vidi sve"</string>
+    <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Odaberite aktivnost"</string>
+    <string name="share_action_provider_share_with" msgid="5247684435979149216">"Podijeliti sa"</string>
+    <string name="sending" msgid="3245653681008218030">"Slanje..."</string>
+    <string name="launchBrowserDefault" msgid="2057951947297614725">"Pokretanje preglednika?"</string>
+    <string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
+    <string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
+    <string name="activity_resolver_use_once" msgid="2404644797149173758">"Samo ovaj put"</string>
+    <string name="activity_resolver_work_profiles_support" msgid="185598180676883455">"%1$s ne podržava poslovni profil"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="4617053898167127471">"Tablet"</string>
+    <string name="default_audio_route_name" product="tv" msgid="9158088547603019321">"TV"</string>
+    <string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Slušalice"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvučnici priključne stanice"</string>
+    <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
+    <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Bežični prikaz"</string>
+    <string name="media_route_button_content_description" msgid="591703006349356016">"Prebacuj"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Poveži na uređaj"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Prebaci ekran na uređaj"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Traženje uređajā…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Postavke"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Prekini vezu"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"Skeniranje…"</string>
+    <string name="media_route_status_connecting" msgid="6422571716007825440">"Povezivanje…"</string>
+    <string name="media_route_status_available" msgid="6983258067194649391">"Dostupno"</string>
+    <string name="media_route_status_not_available" msgid="6739899962681886401">"Nije dostupno"</string>
+    <string name="media_route_status_in_use" msgid="4533786031090198063">"U upotrebi"</string>
+    <string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ugrađeni ekran"</string>
+    <string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI ekran"</string>
+    <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Nadsloj #<xliff:g id="ID">%1$d</xliff:g>"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string>
+    <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", osigurano"</string>
+    <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Zaboravili ste uzorak?"</string>
+    <string name="kg_wrong_pattern" msgid="1850806070801358830">"Pogrešan uzorak"</string>
+    <string name="kg_wrong_password" msgid="2333281762128113157">"Pogrešna lozinka"</string>
+    <string name="kg_wrong_pin" msgid="1131306510833563801">"Pogrešan PIN"</string>
+    <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Broj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER">%1$d</xliff:g>."</string>
+    <string name="kg_pattern_instructions" msgid="398978611683075868">"Nacrtajte obrazac"</string>
+    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Unesite PIN za SIM"</string>
+    <string name="kg_pin_instructions" msgid="2377242233495111557">"Unesite PIN"</string>
+    <string name="kg_password_instructions" msgid="5753646556186936819">"Unesite lozinku"</string>
+    <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM je sada onemogućen. Unesite PUK kôd da nastavite. Obratite se operateru za detalje."</string>
+    <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Unesite željeni PIN kôd"</string>
+    <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrdi željeni PIN kôd"</string>
+    <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Otključavanje SIM kartice…"</string>
+    <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Pogrešan PIN kôd."</string>
+    <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Unesite PIN koji sadrži od 4 do 8 brojeva."</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kôd bi trebao imati 8 brojeva."</string>
+    <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM."</string>
+    <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodovi se ne poklapaju"</string>
+    <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Previše pokušaja otključavanja pomoću uzorka"</string>
+    <string name="kg_login_instructions" msgid="1100551261265506448">"Da otključate, prijavite se sa svojim Google računom."</string>
+    <string name="kg_login_username_hint" msgid="5718534272070920364">"Korisničko ime (adresa e-pošte)"</string>
+    <string name="kg_login_password_hint" msgid="9057289103827298549">"Lozinka"</string>
+    <string name="kg_login_submit_button" msgid="5355904582674054702">"Prijava"</string>
+    <string name="kg_login_invalid_input" msgid="5754664119319872197">"Pogrešno korisničko ime ili lozinka."</string>
+    <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Zaboravili ste korisničko ime ili lozinku?\nPosjetite "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="kg_login_checking_password" msgid="1052685197710252395">"Provjeravanje računa…"</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Pogrešno ste nacrtali uzorak <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nBroj sekundi do sljedećeg pokušaja: <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"Pokušali ste otključati tablet na pogrešan način <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će biti vraćen na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati TV. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, TV će biti vraćen na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"Pokušali ste otključati telefon na pogrešan način <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, telefon će biti vraćen na fabričke postavke i svi korisnički podaci će biti izgubljeni."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Pokušali ste otključati tablet na pogrešan način <xliff:g id="NUMBER">%d</xliff:g> puta. Tablet će sada biti vraćen na fabričke postavke."</string>
+    <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati TV. TV će sada biti vraćen na fabričke postavke."</string>
+    <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Pokušali ste otključati telefon na pogrešan način <xliff:g id="NUMBER">%d</xliff:g> puta. Telefon će sada biti vraćen na fabričke postavke."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate tablet pomoću e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Uzorak za otključavanje ste pogrešno nacrtali <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, bit će zatraženo da TV otključate pomoću računa e-pošte.\n\n Pokušajte opet za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako napravite još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate telefon pomoću e-pošte. \n\n Pokušajte ponovo za <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">"Ukloni"</string>
+    <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Želite li pojačati zvuk iznad preporučenog nivoa?\n\nDužim slušanjem glasnog zvuka možete oštetiti sluh."</string>
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Nastavite držati pritisnuta dva prsta da aktivirate način rada za pristupačnost."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Način rada za pristupačnost je omogućen."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Način rada za pristupačnost je poništen."</string>
+    <string name="user_switched" msgid="3768006783166984410">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
+    <string name="user_switching_message" msgid="2871009331809089783">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
+    <string name="user_logging_out_message" msgid="8939524935808875155">"Odjava korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+    <string name="owner_name" msgid="2716755460376028154">"Vlasnik"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"Greška"</string>
+    <string name="error_message_change_not_allowed" msgid="1347282344200417578">"Promjenu ne dopušta vaš administrator"</string>
+    <string name="app_not_found" msgid="3429141853498927379">"Nije pronađena aplikacija koja će upravljati ovom akcijom."</string>
+    <string name="revoke" msgid="5404479185228271586">"Opozovi"</string>
+    <string name="mediasize_iso_a0" msgid="1994474252931294172">"ISO A0"</string>
+    <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
+    <string name="mediasize_iso_a2" msgid="3097535991925798280">"ISO A2"</string>
+    <string name="mediasize_iso_a3" msgid="3023213259314236123">"ISO A3"</string>
+    <string name="mediasize_iso_a4" msgid="231745325296873764">"ISO A4"</string>
+    <string name="mediasize_iso_a5" msgid="3484327407340865411">"ISO A5"</string>
+    <string name="mediasize_iso_a6" msgid="4861908487129577530">"ISO A6"</string>
+    <string name="mediasize_iso_a7" msgid="5890208588072936130">"ISO A7"</string>
+    <string name="mediasize_iso_a8" msgid="4319425041085816612">"ISO A8"</string>
+    <string name="mediasize_iso_a9" msgid="4882220529506432008">"ISO A9"</string>
+    <string name="mediasize_iso_a10" msgid="2382866026365359391">"ISO A10"</string>
+    <string name="mediasize_iso_b0" msgid="3651827147402009675">"ISO B0"</string>
+    <string name="mediasize_iso_b1" msgid="6072859628278739957">"ISO B1"</string>
+    <string name="mediasize_iso_b2" msgid="1348731852150380378">"ISO B2"</string>
+    <string name="mediasize_iso_b3" msgid="2612510181259261379">"ISO B3"</string>
+    <string name="mediasize_iso_b4" msgid="695151378838115434">"ISO B4"</string>
+    <string name="mediasize_iso_b5" msgid="4863754285582212487">"ISO B5"</string>
+    <string name="mediasize_iso_b6" msgid="5305816292139647241">"ISO B6"</string>
+    <string name="mediasize_iso_b7" msgid="531673542602786624">"ISO B7"</string>
+    <string name="mediasize_iso_b8" msgid="9164474595708850034">"ISO B8"</string>
+    <string name="mediasize_iso_b9" msgid="282102976764774160">"ISO B9"</string>
+    <string name="mediasize_iso_b10" msgid="4517141714407898976">"ISO B10"</string>
+    <string name="mediasize_iso_c0" msgid="3103521357901591100">"ISO C0"</string>
+    <string name="mediasize_iso_c1" msgid="1231954105985048595">"ISO C1"</string>
+    <string name="mediasize_iso_c2" msgid="927702816980087462">"ISO C2"</string>
+    <string name="mediasize_iso_c3" msgid="835154173518304159">"ISO C3"</string>
+    <string name="mediasize_iso_c4" msgid="5095951985108194011">"ISO C4"</string>
+    <string name="mediasize_iso_c5" msgid="1985397450332305739">"ISO C5"</string>
+    <string name="mediasize_iso_c6" msgid="8147421924174693013">"ISO C6"</string>
+    <string name="mediasize_iso_c7" msgid="8993994925276122950">"ISO C7"</string>
+    <string name="mediasize_iso_c8" msgid="6871178104139598957">"ISO C8"</string>
+    <string name="mediasize_iso_c9" msgid="7983532635227561362">"ISO C9"</string>
+    <string name="mediasize_iso_c10" msgid="5040764293406765584">"ISO C10"</string>
+    <string name="mediasize_na_letter" msgid="2841414839888344296">"Letter"</string>
+    <string name="mediasize_na_gvrnmt_letter" msgid="5295836838862962809">"Government Letter"</string>
+    <string name="mediasize_na_legal" msgid="8621364037680465666">"Legal"</string>
+    <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string>
+    <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string>
+    <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid"</string>
+    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"Index Card 3x5"</string>
+    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"Index Card 4x6"</string>
+    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"Index Card 5x8"</string>
+    <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string>
+    <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string>
+    <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string>
+    <string name="mediasize_chinese_roc_8k" msgid="3626855847189438896">"ROC 8K"</string>
+    <string name="mediasize_chinese_roc_16k" msgid="9182191577022943355">"ROC 16K"</string>
+    <string name="mediasize_chinese_prc_1" msgid="4793232644980170500">"PRC 1"</string>
+    <string name="mediasize_chinese_prc_2" msgid="5404109730975720670">"PRC 2"</string>
+    <string name="mediasize_chinese_prc_3" msgid="1335092253339363526">"PRC 3"</string>
+    <string name="mediasize_chinese_prc_4" msgid="9167997800486569834">"PRC 4"</string>
+    <string name="mediasize_chinese_prc_5" msgid="845875168823541497">"PRC 5"</string>
+    <string name="mediasize_chinese_prc_6" msgid="3220325667692648789">"PRC 6"</string>
+    <string name="mediasize_chinese_prc_7" msgid="1776792138507038527">"PRC 7"</string>
+    <string name="mediasize_chinese_prc_8" msgid="1417176642687456692">"PRC 8"</string>
+    <string name="mediasize_chinese_prc_9" msgid="4785983473123798365">"PRC 9"</string>
+    <string name="mediasize_chinese_prc_10" msgid="7847982299391851899">"PRC 10"</string>
+    <string name="mediasize_chinese_prc_16k" msgid="262793383539980677">"PRC 16K"</string>
+    <string name="mediasize_chinese_om_pa_kai" msgid="5256815579447959814">"Pa Kai"</string>
+    <string name="mediasize_chinese_om_dai_pa_kai" msgid="7336412963441354407">"Dai Pa Kai"</string>
+    <string name="mediasize_chinese_om_jurro_ku_kai" msgid="6324465444100490742">"Jurro Ku Kai"</string>
+    <string name="mediasize_japanese_jis_b10" msgid="1787262845627694376">"JIS B10"</string>
+    <string name="mediasize_japanese_jis_b9" msgid="3336035783663287470">"JIS B9"</string>
+    <string name="mediasize_japanese_jis_b8" msgid="6195398299104345731">"JIS B8"</string>
+    <string name="mediasize_japanese_jis_b7" msgid="1674621886902828884">"JIS B7"</string>
+    <string name="mediasize_japanese_jis_b6" msgid="4170576286062657435">"JIS B6"</string>
+    <string name="mediasize_japanese_jis_b5" msgid="4899297958100032533">"JIS B5"</string>
+    <string name="mediasize_japanese_jis_b4" msgid="4213158129126666847">"JIS B4"</string>
+    <string name="mediasize_japanese_jis_b3" msgid="8513715307410310696">"JIS B3"</string>
+    <string name="mediasize_japanese_jis_b2" msgid="4777690211897131190">"JIS B2"</string>
+    <string name="mediasize_japanese_jis_b1" msgid="4608142385457034603">"JIS B1"</string>
+    <string name="mediasize_japanese_jis_b0" msgid="7587108366572243991">"JIS B0"</string>
+    <string name="mediasize_japanese_jis_exec" msgid="5244075432263649068">"JIS Exec"</string>
+    <string name="mediasize_japanese_chou4" msgid="4941652015032631361">"Chou4"</string>
+    <string name="mediasize_japanese_chou3" msgid="6387319169263957010">"Chou3"</string>
+    <string name="mediasize_japanese_chou2" msgid="1299112025415343982">"Chou2"</string>
+    <string name="mediasize_japanese_hagaki" msgid="8070115620644254565">"Hagaki"</string>
+    <string name="mediasize_japanese_oufuku" msgid="6049065587307896564">"Oufuku"</string>
+    <string name="mediasize_japanese_kahu" msgid="6872696027560065173">"Kahu"</string>
+    <string name="mediasize_japanese_kaku2" msgid="2359077233775455405">"Kaku2"</string>
+    <string name="mediasize_japanese_you4" msgid="2091777168747058008">"You4"</string>
+    <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"Neodređeni uspravni format"</string>
+    <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"Neodređeni vodoravni format"</string>
+    <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Otkazano"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Greška pri pisanju sadržaja"</string>
+    <string name="reason_unknown" msgid="6048913880184628119">"nepoznat"</string>
+    <string name="reason_service_unavailable" msgid="7824008732243903268">"Usluga štampanja nije omogućena."</string>
+    <string name="print_service_installed_title" msgid="2246317169444081628">"Usluga <xliff:g id="NAME">%s</xliff:g> je instalirana"</string>
+    <string name="print_service_installed_message" msgid="5897362931070459152">"Dodirnite da omogućite"</string>
+    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"Unesite administratorski PIN"</string>
+    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
+    <string name="restr_pin_incorrect" msgid="8571512003955077924">"Netačno"</string>
+    <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
+    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
+    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"Potvrdi novi PIN"</string>
+    <string name="restr_pin_create_pin" msgid="8017600000263450337">"Kreiraj PIN za izmjenu ograničenja"</string>
+    <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN-ovi se ne podudaraju. Pokušajte ponovo."</string>
+    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN je prekratak. Mora imati najmanje 4 cifre."</string>
+    <plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
+      <item quantity="one">Pokušajte ponovo za <xliff:g id="COUNT">%d</xliff:g> sekundu</item>
+      <item quantity="few">Pokušajte ponovo za <xliff:g id="COUNT">%d</xliff:g> sekunde</item>
+      <item quantity="other">Pokušajte ponovo za <xliff:g id="COUNT">%d</xliff:g> sekundi</item>
+    </plurals>
+    <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije."</string>
+    <string name="immersive_cling_title" msgid="8394201622932303336">"Prikazuje se cijeli ekran"</string>
+    <string name="immersive_cling_description" msgid="3482371193207536040">"Da izađete, prevucite nadolje odozgo."</string>
+    <string name="immersive_cling_positive" msgid="5016839404568297683">"Jasno mi je"</string>
+    <string name="done_label" msgid="2093726099505892398">"Završeno"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač za odabir sata"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač za minute"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Odaberite sat"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Odaberite minute"</string>
+    <string name="select_day" msgid="7774759604701773332">"Odaberite mjesec i dan"</string>
+    <string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Broj <xliff:g id="KEY">%1$s</xliff:g> je izbrisan"</string>
+    <string name="managed_profile_label_badge" msgid="2355652472854327647">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+    <string name="lock_to_app_toast" msgid="7570091317001980053">"Da otkačite ovaj ekran, istovremeno dodirnite i držite Nazad i Pregled."</string>
+    <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Da otkačite ovaj ekran, dodirnite i držite Pregled."</string>
+    <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikačena. Na ovom uređaju nije dozvoljeno otkačivanje."</string>
+    <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
+    <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran je otkačen"</string>
+    <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Traži PIN prije nego se otkači"</string>
+    <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Traži uzorak za otključavanje prije nego se otkači"</string>
+    <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Traži lozinku prije nego se otkači"</string>
     <string name="dock_cropped_windows_text" msgid="6378424064779004428">"Veličina aplikacije nije promjenjiva, pomičite je s dva prsta."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Aplikacija ne podržava dijeljenje ekrana."</string>
-    <!-- no translation found for package_installed_device_owner (8420696545959087545) -->
-    <skip />
-    <!-- no translation found for package_updated_device_owner (8856631322440187071) -->
-    <skip />
-    <!-- no translation found for package_deleted_device_owner (7650577387493101353) -->
-    <skip />
-    <!-- no translation found for battery_saver_description (1960431123816253034) -->
-    <skip />
-    <!-- no translation found for zen_mode_duration_minutes_summary (4367877408072000848) -->
-    <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
-    <!-- no translation found for zen_mode_duration_hours_summary (8152974162096743862) -->
-    <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
-    <!-- no translation found for zen_mode_duration_minutes (5127407202506485571) -->
-    <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
-    <!-- no translation found for zen_mode_duration_hours (3938821308277433854) -->
-    <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
-    <!-- no translation found for zen_mode_until (7336308492289875088) -->
-    <skip />
-    <!-- no translation found for zen_mode_alarm (9128205721301330797) -->
-    <skip />
-    <!-- no translation found for zen_mode_forever (7420011936770086993) -->
-    <skip />
-    <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) -->
-    <skip />
-    <!-- no translation found for zen_mode_rule_name_combination (191109939968076477) -->
-    <skip />
-    <!-- no translation found for toolbar_collapse_description (2821479483960330739) -->
-    <skip />
-    <!-- no translation found for zen_mode_feature_name (5254089399895895004) -->
-    <skip />
-    <!-- no translation found for zen_mode_downtime_feature_name (2626974636779860146) -->
-    <skip />
-    <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
-    <skip />
-    <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
-    <skip />
-    <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
-    <skip />
-    <!-- no translation found for muted_by (6147073845094180001) -->
-    <skip />
-    <!-- no translation found for system_error_wipe_data (6608165524785354962) -->
-    <skip />
-    <!-- no translation found for system_error_manufacturer (8086872414744210668) -->
-    <skip />
-    <!-- no translation found for stk_cc_ussd_to_dial (5202342984749947872) -->
-    <skip />
-    <!-- no translation found for stk_cc_ussd_to_ss (2345360594181405482) -->
-    <skip />
-    <!-- no translation found for stk_cc_ussd_to_ussd (7466087659967191653) -->
-    <skip />
-    <!-- no translation found for stk_cc_ss_to_dial (2151304435775557162) -->
-    <skip />
-    <!-- no translation found for stk_cc_ss_to_ussd (3951862188105305589) -->
-    <skip />
-    <!-- no translation found for stk_cc_ss_to_ss (5470768854991452695) -->
-    <skip />
-    <!-- no translation found for notification_work_profile_content_description (4600554564103770764) -->
-    <skip />
-    <!-- no translation found for usb_midi_peripheral_name (7221113987741003817) -->
-    <skip />
-    <!-- no translation found for usb_midi_peripheral_manufacturer_name (7176526170008970168) -->
-    <skip />
-    <!-- no translation found for usb_midi_peripheral_product_name (4971827859165280403) -->
-    <skip />
-    <!-- no translation found for floating_toolbar_open_overflow_description (4797287862999444631) -->
-    <skip />
-    <!-- no translation found for floating_toolbar_close_overflow_description (559796923090723804) -->
-    <skip />
-    <!-- no translation found for maximize_button_text (7543285286182446254) -->
-    <skip />
-    <!-- no translation found for close_button_text (3937902162644062866) -->
-    <skip />
-    <!-- no translation found for selected_count (7187339492915744615) -->
-    <!-- no translation found for default_notification_topic_label (227586145791870829) -->
-    <skip />
-    <!-- no translation found for importance_from_topic (3572280439880023233) -->
-    <skip />
-    <!-- no translation found for importance_from_person (9160133597262938296) -->
-    <skip />
+    <string name="package_installed_device_owner" msgid="8420696545959087545">"Instalirao administrator"</string>
+    <string name="package_updated_device_owner" msgid="8856631322440187071">"Ažurirao administrator"</string>
+    <string name="package_deleted_device_owner" msgid="7650577387493101353">"Izbrisao administrator"</string>
+    <string name="battery_saver_description" msgid="1960431123816253034">"Da bi se trajanje baterije produžilo, opcija za štednju baterije minimizira rad uređaja i ograničava vibriranje, usluge lokacije i većinu prijenosa podataka u pozadini. E-pošta, poruke i druge aplikacije koje se oslanjaju na sinhronizaciju ne mogu biti ažurirane dok ih ne otvorite.\n\nŠtednja baterije se automatski isključi prilikom punjenja uređaja."</string>
+    <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
+      <item quantity="one">%1$d minuta (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="few">%1$d minute (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">%1$d minuta (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="6830154222366042597">
+      <item quantity="one">%1$d min (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="few">%1$d min (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">%1$d min (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
+      <item quantity="one">%1$d sat (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="few">%1$d sata (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">%1$d sati (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="4787552595253082371">
+      <item quantity="one">%1$d sat (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="few">%1$d sata (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+      <item quantity="other">%1$d sati (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
+    </plurals>
+    <plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
+      <item quantity="one">%d minuta</item>
+      <item quantity="few">%d minute</item>
+      <item quantity="other">%d minuta</item>
+    </plurals>
+    <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2199350154433426128">
+      <item quantity="one">%d min</item>
+      <item quantity="few">%d min</item>
+      <item quantity="other">%d min</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
+      <item quantity="one">%d sat</item>
+      <item quantity="few">%d sata</item>
+      <item quantity="other">%d sati</item>
+    </plurals>
+    <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="6748277774662434217">
+      <item quantity="one">%d sat</item>
+      <item quantity="few">%d sata</item>
+      <item quantity="other">%d sati</item>
+    </plurals>
+    <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
+    <string name="zen_mode_forever" msgid="7420011936770086993">"Dok ovo ne isključite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dok ne isključite opciju Ne ometaj"</string>
+    <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
+    <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skupi"</string>
+    <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string>
+    <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Odmor"</string>
+    <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Radni dan uveče"</string>
+    <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Vikend"</string>
+    <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Događaj"</string>
+    <string name="muted_by" msgid="6147073845094180001">"Ton isključila aplikacija <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"Postoji problem u vašem uređaju i može biti nestabilan dok ga ne vratite na fabričke postavke."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"Postoji problem u vašem uređaju. Za više detalja obratite se proizvođaču."</string>
+    <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD zahtjev je izmijenjen u DIAL zahtjev."</string>
+    <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD zahtjev je izmijenjen u SS zahtjev."</string>
+    <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD zahtjev je izmijenjen u novi USSD zahtjev."</string>
+    <string name="stk_cc_ss_to_dial" msgid="2151304435775557162">"SS zahtjev je izmijenjen u DIAL zahtjev."</string>
+    <string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS zahtjev je izmijenjen u USSD zahtjev."</string>
+    <string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS zahtjev je izmijenjen u novi SS zahtjev."</string>
+    <string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil za posao"</string>
+    <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ulaz za periferijske uređaje"</string>
+    <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
+    <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ulaz za periferijske uređaje"</string>
+    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Još opcija"</string>
+    <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Zatvori preklopni meni"</string>
+    <string name="maximize_button_text" msgid="7543285286182446254">"Povećaj maksimalno"</string>
+    <string name="close_button_text" msgid="3937902162644062866">"Zatvori"</string>
+    <plurals name="selected_count" formatted="false" msgid="7187339492915744615">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item>
+    </plurals>
+    <string name="default_notification_topic_label" msgid="227586145791870829">"Razno"</string>
+    <string name="importance_from_topic" msgid="3572280439880023233">"Vi postavljate značaj ovih oabvještenja."</string>
+    <string name="importance_from_person" msgid="9160133597262938296">"Ovo je značajno zbog osoba koje su uključene."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"Da li dozvoljate da <xliff:g id="APP">%1$s</xliff:g> kreira novog korisnika za nalog <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="user_creation_adding" msgid="4482658054622099197">"Da li dozvoljavate da <xliff:g id="APP">%1$s</xliff:g> kreira novog korisnika za <xliff:g id="ACCOUNT">%2$s</xliff:g> (Korisnik sa ovim nalogom već postoji)?"</string>
-    <!-- no translation found for language_selection_title (7181332986330337171) -->
-    <skip />
-    <!-- no translation found for country_selection_title (2954859441620215513) -->
-    <skip />
-    <!-- no translation found for search_language_hint (7042102592055108574) -->
-    <skip />
-    <!-- no translation found for language_picker_section_suggested (8414489646861640885) -->
-    <skip />
-    <!-- no translation found for language_picker_section_all (3097279199511617537) -->
-    <skip />
-    <!-- no translation found for locale_search_menu (2560710726687249178) -->
-    <skip />
-    <string name="work_mode_off_title" msgid="8954725060677558855">"Radni način je ISKLJUČEN"</string>
-    <string name="work_mode_off_message" msgid="3286169091278094476">"Omogućava radnom profilu da funkcioniše, uključujući aplikacije, sinhronizaciju u pozadini i povezane funkcije."</string>
+    <string name="language_selection_title" msgid="7181332986330337171">"Izbor jezika"</string>
+    <string name="country_selection_title" msgid="2954859441620215513">"Izbor regije"</string>
+    <string name="search_language_hint" msgid="7042102592055108574">"Ukucajte naziv jezika"</string>
+    <string name="language_picker_section_suggested" msgid="8414489646861640885">"Predloženo"</string>
+    <string name="language_picker_section_all" msgid="3097279199511617537">"Svi jezici"</string>
+    <string name="locale_search_menu" msgid="2560710726687249178">"Pretraga"</string>
+    <string name="work_mode_off_title" msgid="8954725060677558855">"Radni način rada je ISKLJUČEN"</string>
+    <string name="work_mode_off_message" msgid="3286169091278094476">"Omogući radnom profilu da funkcionira, uključujući aplikacije, sinhronizaciju u pozadini i povezane funkcije."</string>
     <string name="work_mode_turn_on" msgid="2062544985670564875">"Uključi"</string>
     <string name="suspended_package_title" msgid="3408150347778524435">"%1$s – onemogućeno"</string>
     <string name="suspended_package_message" msgid="6341091587106868601">"Onemogućio administrator (%1$s). Obratite mu se za više informacija."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Neke funkcije možda neće biti dostupne"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Dodirnite da biste nastavili"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil korisnika je zaključan"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Neke funkcije mogu biti ograničene"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Dodirnite da biste otključali"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Podaci korisnika su zaključani"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Radni profil je zaključan"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirnite da biste otključali radni profil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Povezan na uređaj <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite za prikaz fajlova"</string>
     <string name="pin_target" msgid="3052256031352291362">"Zakači"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index fe7dbc7..f9ecd06 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca per veure més opcions."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca per desactivar la depuració USB"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vols compartir l\'informe d\'errors amb l\'administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"El teu administrador de TI ha sol·licitat un informe d\'errors per tal de resoldre problemes"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTA"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REBUTJA"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"S\'està creant l\'informe d\'errors…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca per cancel·lar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tria els teclats"</string>
     <string name="show_ime" msgid="2506087537466597099">"El deixa a la pantalla mentre el teclat físic està actiu"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"L\'administrador de l\'empresa %1$s ha desactivat el paquet. Contacta-hi per obtenir-ne més informació."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tens missatges nous"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Obre l\'aplicació de SMS per veure\'ls"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Hi pot haver funcions no disponibles"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toca per continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil d\'usuari bloquejat"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Algunes funcions es limitaran"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toca per desbloquejar"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dades d\'usuari bloquejades"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil professional bloquejat"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca per desbloquejar el perfil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"S\'ha connectat a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca per veure els fitxers"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixa"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 0b6d668..19f8864 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Klepnutím zobrazíte další možnosti."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Sdílet zprávu o chybě s administrátorem?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administrátor IT si vyžádal zprávu o chybě, aby mohl problém odstranit."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PŘIJMOUT"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODMÍTNOUT"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Vytváření zprávy o chybě…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Klepnutím zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Změna klávesnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrat klávesnici"</string>
     <string name="show_ime" msgid="2506087537466597099">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Zakázáno administrátorem zařízení %1$s. Chcete-li získat další informace, kontaktujte jej."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Máte nové zprávy"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Zobrazíte je v aplikaci pro SMS"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Některé funkce nemusí být k dispozici"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Pokračujte klepnutím"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Uživatelský profil je uzamčen"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funkce mohou být omezeny"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Klepnutím je odemknete"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Uživatelská data jsou uzamčena"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Pracovní profil je uzamčen"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Klepnutím jej odemknete"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Připojeno k zařízení <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Klepnutím zobrazíte soubory"</string>
     <string name="pin_target" msgid="3052256031352291362">"Připnout"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4a3780c..6c36d86 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tryk for at se flere muligheder."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vil du dele fejlrapporten med administratoren?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Din it-administrator har anmodet om en fejlrapport for bedre at kunne finde og rette fejlen"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTÉR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AFVIS"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Opretter fejlrapport…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryk for at annullere"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skift tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vælg tastaturer"</string>
     <string name="show_ime" msgid="2506087537466597099">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Deaktiveret af %1$s administrator. Kontakt vedkommende for at få flere oplysninger."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du har nye beskeder"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Åbn sms-appen for at se beskeden"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Nogle funktioner er muligvis ikke tilgængelige"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Tryk for at fortsætte"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Brugerprofilen er låst"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Nogle funktioner er begrænsede"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tryk for at låse op"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Brugerdataene er låst"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Arbejdsprofilen er låst"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tryk for at låse profilen op"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tilsluttet <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tryk for at se filer"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fastgør"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f04521f..b68c7a1 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Für weitere Optionen tippen"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren berühren"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Fehlerbericht mit Administrator teilen?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Dein IT-Administrator hat einen Fehlerbericht zur Fehlerbehebung angefordert."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AKZEPTIEREN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ABLEHNEN"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Fehlerbericht wird aufgerufen…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Zum Abbrechen tippen"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatur ändern"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Tastatur auswählen"</string>
     <string name="show_ime" msgid="2506087537466597099">"Auf dem Display einblenden, wenn die physische Tastatur aktiv ist"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Durch den Administrator von %1$s deaktiviert. Setze dich für weitere Informationen mit ihm in Verbindung."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du hast neue Nachrichten"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Zum Ansehen SMS-App öffnen"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Einige Funktionen sind evtl. nicht verfügbar"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Zum Fortfahren tippen"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Nutzerprofil gesperrt"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Einige Funktionen sind evtl. eingeschränkt"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Zum Entsperren tippen"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Nutzerdaten gesperrt"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Arbeitsprofil gesperrt"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Zum Entsperren des Arbeitsprofils tippen"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Verbunden mit <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Zum Ansehen der Dateien tippen"</string>
     <string name="pin_target" msgid="3052256031352291362">"Markieren"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c557c73..63d49b1 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Αγγίξτε για περισσότερες επιλογές."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Απεν. του εντοπ. σφαλμάτων USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Να κοινοποιηθεί η αναφορά σφάλματος στο διαχειριστή;"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ο διαχειριστής σας IT ζήτησε μια αναφορά σφάλματος για να συμβάλει στην αντιμετώπιση του προβλήματος"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ΑΠΟΔΟΧΗ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ΑΠΟΡΡΙΨΗ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Λήψη αναφοράς σφάλματος…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Αγγίξτε για ακύρωση"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Επιλογή πληκτρολογίων"</string>
     <string name="show_ime" msgid="2506087537466597099">"Να παραμένει στην οθόνη όταν είναι ενεργό το φυσικό πληκτρολόγιο"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Απενεργοποιήθηκε από το διαχειριστή της συσκευής %1$s. Επικοινωνήστε με το διαχειριστή για να μάθετε περισσότερα."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Έχετε νέα μηνύματα"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Άνοιγμα της εφαρμογής SMS για προβολή"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Ενδεχόμενο μη διαθέσιμων λειτουργιών"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Αγγίξτε για συνέχεια"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Το προφίλ χρήστη κλειδώθηκε"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Μερ. λειτ. ίσως είναι περιορ."</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Πατήστε για ξεκλείδωμα"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Τα δεδομένα χρήστη κλειδώθηκαν"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Το προφίλ εργασίας κλειδώθηκε"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Πατήστε για ξεκλ. προφίλ εργ."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Συνδέθηκε με το <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Πατήστε για να δείτε τα αρχεία"</string>
     <string name="pin_target" msgid="3052256031352291362">"Καρφίτσωμα"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index a0a5493..7a709b6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Disabled by %1$s administrator. Contact them to find out more."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"You have new messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Open SMS app to view"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Some functions might not be available"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Touch to continue"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"User profile locked"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Some functionality may be limited"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tap to unlock"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"User data locked"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Work profile locked"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a0a5493..7a709b6 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Disabled by %1$s administrator. Contact them to find out more."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"You have new messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Open SMS app to view"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Some functions might not be available"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Touch to continue"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"User profile locked"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Some functionality may be limited"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tap to unlock"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"User data locked"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Work profile locked"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a0a5493..7a709b6 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touch for more options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Touch to disable USB debugging."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Share bug report with admin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Your IT admin requested a bug report to help troubleshoot"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPT"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"DECLINE"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Taking bug report…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touch to cancel"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choose keyboards"</string>
     <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Disabled by %1$s administrator. Contact them to find out more."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"You have new messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Open SMS app to view"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Some functions might not be available"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Touch to continue"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"User profile locked"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Some functionality may be limited"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tap to unlock"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"User data locked"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Work profile locked"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tap to unlock work profile"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connected to <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tap to view files"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pin"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f07745b..465eceb 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver más opciones."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración por USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"¿Quieres compartir el informe de errores con el administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"El administrador de TI solicitó un informe de errores para ayudar a solucionar el problema"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECHAZAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Realizando un informe de errores…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar el teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Mantener en la pantalla cuando el teclado físico está activo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"El administrador de %1$s lo inhabilitó. Comunícate con él para obtener más información."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tienes mensajes nuevos"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abrir app de SMS para ver el mensaje"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Funciones no disponibles"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Tocar para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil de usuario bloqueado"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funciones limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Presiona para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Datos del usuario bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de trabajo bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Presiona para desbloquear"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Presiona para ver archivos"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fijar"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 518b157..2a0e000 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para obtener más opciones"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para inhabilitarla"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"¿Compartir informe de errores con el administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Tu administrador de TI ha solicitado un informe de errores para solucionar problemas"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECHAZAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Creando informe de errores…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toca para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Elegir teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Debe seguir en pantalla mientras el teclado físico esté activo"</string>
@@ -1559,9 +1565,11 @@
     <skip />
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tienes mensajes nuevos"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abre la aplicación de SMS para ver el mensaje"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Algunas funciones no disponibles"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toca para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil de usuario bloqueado"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Algunas funciones limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toca para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Datos de usuario bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de trabajo bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca para desbloquear"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca para ver archivos"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fijar"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index bb48bd7..15ba404 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Puudutage rohkemate valikute kuvamiseks."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Kas jagada veaaruannet administraatoriga?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administraator taotles veaaruannet, mis aitaks vigu otsida"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"NÕUSTU"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"KEELDU"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Veaaruande võtmine …"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Puudutage tühistamiseks"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatuuri muutmine"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vali klaviatuurid"</string>
     <string name="show_ime" msgid="2506087537466597099">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Keelas seadme %1$s administraator. Lisateabe saamiseks võtke temaga ühendust."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Teile on uusi sõnumeid"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Avage vaatamiseks SMS-rakendus"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Mõni funktsioon pole võib-olla saadaval"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Puudutage jätkamiseks"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Kasutajaprofiil on lukustatud"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funktsioon võib olla piiratud"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Avamiseks puudutage"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Kasutaja andmed on lukustatud"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Tööprofiil on lukustatud"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Puudut. tööprofiili avamiseks"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ühendatud seadmega <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Failide vaatamiseks puudutage"</string>
     <string name="pin_target" msgid="3052256031352291362">"Kinnita"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index a595603..b8fa962 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Ukitu aukera gehiago ikusteko."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB arazketa desgaitzeko, ukitu hau."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partekatu nahi duzu administratzailearekin akatsen txostena?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IKT administratzaileak akatsen txostena eskatu du arazoa konpontzen laguntzeko"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ONARTU"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"BAZTERTU"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Akatsen txostena sortzen…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Ukitu bertan behera uzteko"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Aldatu teklatua"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Aukeratu teklatuak"</string>
     <string name="show_ime" msgid="2506087537466597099">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Desgaitu egin du %1$s gailuaren administratzaileak. Informazio gehiago lortu nahi baduzu, jarri harekin harremanetan."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Mezu berriak dituzu"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Mezuak ikusteko, ireki SMS mezuen aplikazioa"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Baliteke funtzio batzuk ez egotea"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Ukitu jarraitzeko"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Blokeatuta dago profila"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funtzioak mugatuta egon litezke"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Sakatu desblokeatzeko"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Blokeatuta daude datuak"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Blokeatuta dago laneko profila"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Sakatu profila desblokeatzeko"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> zerbitzura konektatuta"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Sakatu fitxategiak ikusteko"</string>
     <string name="pin_target" msgid="3052256031352291362">"Ainguratu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 14b87e8..02eafe9 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -890,7 +890,7 @@
     <string name="yes" msgid="5362982303337969312">"تأیید"</string>
     <string name="no" msgid="5141531044935541497">"لغو"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"توجه"</string>
-    <string name="loading" msgid="7933681260296021180">"در حال بارگیری..."</string>
+    <string name="loading" msgid="7933681260296021180">"در حال بارکردن…"</string>
     <string name="capital_on" msgid="1544682755514494298">"روشن"</string>
     <string name="capital_off" msgid="6815870386972805832">"خاموش"</string>
     <string name="whichApplication" msgid="4533185947064773386">"تکمیل عملکرد با استفاده از"</string>
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"برای گزینه‌های بیشتر لمس کنید."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏اشکال‌زدایی USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏غیرفعال‌کردن اشکال‌زدایی‌USB: با لمس آن."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"گزارش اشکال را با سرپرست سیستم به اشتراک می‌گذارید؟"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"سرپرست فناوری اطلاعات شما برای کمک به عیب‌یابی، گزارش اشکال درخواست کرد"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"پذیرفتن"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"نپذیرفتن"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"درحال گرفتن گزارش اشکال…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"برای لغو کردن لمس کنید"</string>
     <string name="select_input_method" msgid="8547250819326693584">"تغییر صفحه‌کلید"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"انتخاب صفحه‌کلیدها"</string>
     <string name="show_ime" msgid="2506087537466597099">"وقتی صفحه‌کلید فیزیکی فعال است این ویرایشگر را روی صفحه نگه‌می‌دارد"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"‏سرپرست %1$s آن را غیرفعال کرده است. برای اطلاعات بیشتر با او تماس بگیرید."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"پیام‌های جدیدی دارید"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"برای مشاهده، برنامه پیامک را باز کنید"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"شاید برخی عملکردها دردسترس نباشند"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"برای ادامه لمس کنید"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"نمایه کاربر قفل است"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ممکن است برخی از عملکردها محدود باشند"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"برای باز کردن قفل، ضربه بزنید"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"داده‌های کاربر قفل هستند"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"نمایه کاری قفل است"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"برای باز کردن قفل ضربه بزنید"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"به <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> متصل شد"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"برای دیدن فایل‌ها، ضربه بزنید"</string>
     <string name="pin_target" msgid="3052256031352291362">"پین کردن"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index c15c3db..812565a 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Lisää vaihtoehtoja koskettamalla"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sulje USB-vianetsintä koskettamalla."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Jaetaanko virheraportti järjestelmänvalvojalle?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-järjestelmänvalvojasi pyysi virheraporttia voidakseen auttaa vianetsinnässä."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"HYVÄKSY"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"HYLKÄÄ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Luodaan virheraporttia…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Peruuta koskettamalla"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Valitse näppäimistöt"</string>
     <string name="show_ime" msgid="2506087537466597099">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen."</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Organisaation %1$s järjestelmänvalvojan käytöstä poistama. Kysy häneltä lisätietoja."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Sinulle on uusia viestejä"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Katso avaamalla tekstiviestisovellus."</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Osaa toiminnoista ei ehkä voi käyttää"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Jatka koskettamalla."</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Käyttäjäprofiili on lukittu."</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Toimintorajoitus mahdollinen"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Avaa napauttamalla."</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Käyttäjän tiedot on lukittu."</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Työprofiili on lukittu."</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Avaa profiili koskettamalla."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> yhdistetty"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Näytä tiedostot koskettamalla"</string>
     <string name="pin_target" msgid="3052256031352291362">"Kiinnitä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 3443d4d..d6c933f 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Touchez pour afficher plus d\'options."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partager le rapport de bogue avec l\'administrateur?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Votre administrateur informatique a demandé un rapport de bogue pour l\'aider à résoudre le problème"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTER"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUSER"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Création d\'un rapport de bogue en cours..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Touchez pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Choisir les claviers"</string>
     <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Cette option a été désactivée par l\'administrateur de %1$s. Communiquez avec lui pour en savoir plus."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Vous avez de nouveaux messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Certaines fonct. p-ê non dispo."</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Touchez pour continuer"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil d\'utilisateur verrouillé"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Certaines fonct. sont limitées"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Touchez pour déverrouiller"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Données utilisat. verrouillées"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil professionnel verrouillé"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Touch. pr déver. profil profess."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Touchez ici pour afficher les fichiers"</string>
     <string name="pin_target" msgid="3052256031352291362">"Épingler"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 662076d..897a289 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Appuyez pour afficher plus d\'options"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désact. débogage USB"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Partager le rapport de bug avec l\'administrateur ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Votre administrateur informatique a demandé un rapport de bug pour l\'aider à résoudre le problème."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTER"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUSER"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Création du rapport de bug…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Appuyer pour annuler"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Sélectionner des claviers"</string>
     <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Désactivé par l\'administrateur %1$s. Contactez-le pour en savoir plus."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Vous avez de nouveaux messages"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ouvrir l\'application de SMS pour afficher le message"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Certaines fonctions potentiellement non dispos"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Appuyer pour continuer"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil utilisateur verrouillé"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Des fonctionnalités peuvent être limitées"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Appuyer pour déverrouiller"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Infos sur utilis. verrouillées"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil professionnel verrouillé"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"App. pour déver. profil profes."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connecté à <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Appuyez ici pour voir les fichiers."</string>
     <string name="pin_target" msgid="3052256031352291362">"Épingler"</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index f2e1850..0e54aad 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver máis opcións."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para desactivala"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Queres compartir o informe de erros co administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"O teu administrador de TI solicitou un informe de erros para axudar a solucionar problemas"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEPTAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ANULAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Creando informe de erros…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocar para cancelar o informe de erros"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Manteno na pantalla mentres o teclado físico estea activo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"O administrador de %1$s desactivou este paquete. Contacta con el para obter máis información."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tes mensaxes novas"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abre a aplicación de SMS para ver as mensaxes"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Quizais haxa funcións non dispoñibles"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toca para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Bloqueouse o perfil do usuario"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Pode haber funcións limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toca para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Datos do usuario bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de traballo bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toca para desbloquear o perfil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toca para ver os ficheiros"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixar"</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index ec613b0..246f2b4 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"વધુ વિકલ્પો માટે ટચ કરો."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ડીબગિંગ અક્ષમ કરવા માટે ટચ કરો."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"વ્યવસ્થાપક સાથે બગ રિપોર્ટ શેર કરીએ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"તમારા IT વ્યવસ્થાપક એ સમસ્યા નિવારણમાં સહાય માટે બગ રિપોર્ટની વિનંતી કરી છે"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"સ્વીકારો"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"નકારો"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"રદ કરવા માટે ટચ કરો"</string>
     <string name="select_input_method" msgid="8547250819326693584">"કીબોર્ડ બદલો"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"કીબોર્ડ્સ પસંદ કરો"</string>
     <string name="show_ime" msgid="2506087537466597099">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ. વધુ જાણવા માટે તેમનો સંપર્ક કરો."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"તમારી પાસે નવા સંદેશા છે"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"જોવા માટે SMS ઍપ્લિકેશન ખોલો"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"કેટલાક કાર્યો કદાચ ઉપલબ્ધ ન હોય"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ચાલુ રાખવા માટે ટચ કરો"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"વપરાશકર્તા પ્રોફાઇલ લૉક કરી"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"કેટલીક કાર્યક્ષમતા મર્યાદિત હોઈ શકે છે"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"અનલૉક કરવા માટે ટૅપ કરો"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"વપરાશકર્તા ડેટા લૉક કર્યો"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"કાર્ય પ્રોફાઇલ લૉક કરી"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"કાર્ય પ્રોફાઇલ અનલૉક કરવા ટૅપ કરો"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> થી કનેક્ટ કરેલું છે"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ફાઇલો જોવા માટે ટૅપ કરો"</string>
     <string name="pin_target" msgid="3052256031352291362">"પિન કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 4c944c30..5e76c16 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"और विकल्पों के लिए स्पर्श करें."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करना अक्षम करने के लिए स्‍पर्श करें."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"व्यवस्थापक के साथ बग रिपोर्ट साझा करें?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"समस्या निवारण में सहायता हेतु आपके आईटी व्यवस्थापक ने बग रिपोर्ट के लिए अनुरोध किया है"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार करें"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"अस्वीकार करें"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"बग रिपोर्ट प्राप्त की जा रही है…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करने के लिए स्पर्श करें"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string>
     <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड के सक्रिय होने के दौरान इसे स्‍क्रीन पर बनाए रखें"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s व्‍यवस्‍थापक द्वारा अक्षम किया गया. अधिक जानने के लिए उनसे संपर्क करें."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"आपके पास नए संदेश हैं"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"देखने के लिए SMS ऐप खोलें"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"संभवत: कुछ फंक्‍शन उपलब्‍ध न हों"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"जारी रखने के लिए स्‍पर्श करें"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"उपयोगकर्ता प्रोफ़ाइल लॉक है"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"कुछ कार्य क्षमताएं सीमित हो सकती हैं"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"अनलॉक करने के लिए टैप करें"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"उपयोगकर्ता डेटा लॉक किया गया"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"कार्य प्रोफ़ाइल लॉक है"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाइल अनलॉक करने हेतु टैप करें"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> से कनेक्ट किया गया"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फ़ाइलें देखने के लिए टैप करें"</string>
     <string name="pin_target" msgid="3052256031352291362">"पिन करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 855e1f7..619e9b9 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1061,12 +1061,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za više opcija."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje pogrešaka USB-om"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da se onemogući otklanjanje pogrešaka USB-om."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite li podijeliti izvješće o programskoj pogrešci s administratorom?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Vaš IT administrator zatražio je izvješće o programskoj pogrešci radi lakšeg rješavanja problema"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIHVATI"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODBIJ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Izrada izvješća o programskoj pogrešci…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dodirnite da biste otkazali"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Promjena tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Odaberi tipkovnice"</string>
     <string name="show_ime" msgid="2506087537466597099">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string>
@@ -1574,9 +1580,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Onemogućio administrator (%1$s). Obratite mu se za više informacija."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nove poruke"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorite SMS aplikaciju da biste pregledali poruke"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Možda ima nedostupnih funkcija"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Dodirnite da biste nastavili"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Korisnički je profil zaključan"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funkcije mogu biti ograničene"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Dodirnite za otključavanje"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Korisnički podaci zaključani"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Radni je profil zaključan"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Dodirnite za otključavanje"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> – veza je uspostavljena"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dodirnite da biste pregledali datoteke"</string>
     <string name="pin_target" msgid="3052256031352291362">"Prikvači"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index bede998..be2a3fd 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Érintse meg a további lehetőségekhez."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Érintse meg az USB hibakeresés kikapcsolásához."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Megosztja a hibajelentést a rendszergazdával?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"A rendszergazda hibajelentést kért, hogy segíthessen a problémamegoldásban"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ELFOGADOM"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ELUTASÍTOM"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Hibajelentés készítése…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"A visszavonáshoz érintse meg"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Billentyűzet megváltoztatása"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Billentyűzetek kiválasztása"</string>
     <string name="show_ime" msgid="2506087537466597099">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"A(z) %1$s szervezet rendszergazdája letiltotta. További információért vegye fel vele a kapcsolatot."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Új üzenetei érkeztek"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"SMS-alkalmazás megnyitása a megtekintéshez"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Néhány funkció nem használható"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Érintse meg a folytatáshoz"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Felhasználói profil zárolva"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Egyes funkciók korlátozva lehetnek"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Koppintson a feloldáshoz"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Felhasználói adatok zárolva"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Munkahelyi profil zárolva"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"A feloldáshoz koppintson rá"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Csatlakoztatva a(z) <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> eszközhöz"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Koppintson ide a fájlok megtekintéséhez"</string>
     <string name="pin_target" msgid="3052256031352291362">"Rögzítés"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 3890ef8..b436f3d 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ուղարկե՞լ վրիպակի զեկույց ադմինիստրատորին:"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Անսարքությունների վերացման նպատակով ձեր ՏՏ ադմինիստրատորին անհրաժեշտ է վրիպակի զեկույց"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ԸՆԴՈՒՆԵԼ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ՄԵՐԺԵԼ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Վրիպակի զեկույցի ստեղծում…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Հպեք՝ չեղարկելու համար"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Փոխել ստեղնաշարը"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Ընտրել ստեղնաշար"</string>
     <string name="show_ime" msgid="2506087537466597099">"Պահել էկրանին մինչդեռ ֆիզիկական ստեղնաշարն ակտիվ է"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Կասեցվել է %1$s ադմինիստրատորի կողմից: Ավելին իմանալու համար կապվեք նրա հետ:"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Դուք ունեք նոր հաղորդագրություններ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Դիտելու համար բացել SMS հավելվածը"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Հնարավոր է՝ որոշ գործառույթներ հասանելի չլինեն"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Հպեք՝ շարունակելու համար"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Օգտվողի պրոֆիլը կողպված է"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Որոշ գործառույթներ կարող են սահմանափակված լինել"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Հպեք՝ ապակողպելու համար"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Օգտվողի տվյալները կողպված են"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Աշխատանքային պրոֆիլը կողպված է"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Հպեք՝ այն ապակողպելու համար"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Միացված է <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-ին"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Հպեք՝ ֆայլերը տեսնելու համար"</string>
     <string name="pin_target" msgid="3052256031352291362">"Ամրացնել"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 4d4f45e..7c18d24 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sentuh untuk opsi lainnya."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk menonaktifkan debugging USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bagikan laporan bug kepada admin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Admin IT meminta laporan bug untuk membantu memecahkan masalah"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SETUJU"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TOLAK"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Mengambil laporan bug…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ubah keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih keyboard"</string>
     <string name="show_ime" msgid="2506087537466597099">"Pertahankan di layar jika keyboard fisik masih aktif"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Dinonaktifkan oleh administrator %1$s. Hubungi administrator untuk mempelajari lebih lanjut."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Ada pesan baru"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Buka aplikasi SMS untuk melihat"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Beberapa fungsi tidak ada"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Sentuh untuk melanjutkan"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil pengguna terkunci"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Beberapa fungsi mungkin terbatas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Ketuk untuk membuka kunci"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Data pengguna dikunci"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil kerja terkunci"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ketuk untuk membuka kunci profil kerja"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tersambung ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ketuk untuk melihat file"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pasang pin"</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 4ad48a9..79ef76b 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Snertu til að fá fleiri valkosti."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Snertu til að slökkva á USB-villuleit."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Deila villutilkynningu með kerfisstjóra?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Kerfisstjórinn þinn óskaði eftir villutilkynningu til að auðvelda úrræðaleit"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SAMÞYKKJA"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"HAFNA"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Tekur við villutilkynningu…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Snertu til að hætta við"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Skipta um lyklaborð"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velja lyklaborð"</string>
     <string name="show_ime" msgid="2506087537466597099">"Haltu því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Gert óvirkt af stjórnanda %1$s. Hafðu samband við hann til að fá frekari upplýsingar."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Þú ert með ný skilaboð"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Opnaðu SMS-forritið til að skoða"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Sumir eiginleikar e.t.v. ekki í boði"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Snertu til að halda áfram"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Notandaprófíll læstur"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Sum virkni kann að vera takmörkuð"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Ýttu til að opna"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Notendagögn læst"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Vinnusnið læst"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ýttu til að opna vinnusnið"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Tengt við <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ýttu til að skoða skrárnar"</string>
     <string name="pin_target" msgid="3052256031352291362">"Festa"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7cd29d7..2ba3359 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -349,8 +349,8 @@
     <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul tablet, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string>
     <string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Consente all\'app di aggiungere, rimuovere o modificare eventi che è possibile modificare sulla TV, inclusi quelli di amici o colleghi. L\'app potrebbe inviare messaggi apparentemente provenienti dai proprietari del calendario o modificare eventi all\'insaputa dei proprietari."</string>
     <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul telefono, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesso a comandi aggiuntivi del provider di localizz."</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di localizzazione."</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesso a comandi aggiuntivi provider di geolocalizz."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
     <string name="permlab_accessFineLocation" msgid="251034415460950944">"accesso alla posizione esatta (basata su GPS e rete)"</string>
     <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Consente all\'applicazione di ottenere la tua posizione esatta utilizzando il sistema GPS (Global Positioning System) o fonti di geolocalizzazione delle reti come ripetitori di telefonia mobile e Wi-Fi. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul dispositivo per poter essere utilizzati dall\'applicazione. Le applicazioni potrebbero utilizzare questa autorizzazione per stabilire la tua posizione e potrebbero consumare ulteriore batteria."</string>
     <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"accesso alla posizione approssimativa (basata sulla rete)"</string>
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tocca per visualizzare più opzioni."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Condividere la segnalazione di bug con l\'amministratore?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"L\'amministratore IT ha richiesto una segnalazione di bug per poter risolvere più facilmente i problemi"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCETTO"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RIFIUTO"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Recupero della segnalazione di bug…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tocca per annullare"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Cambia tastiera"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Scegli tastiera"</string>
     <string name="show_ime" msgid="2506087537466597099">"Tieni sullo schermo quando è attiva la tastiera fisica"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Disattivato dall\'amministratore di %1$s. Contattalo per ulteriori informazioni."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Hai nuovi messaggi"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Apri l\'app SMS per la visualizzazione"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Alcune funzioni potrebbero non essere disponibili"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Tocca per continuare"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profilo utente bloccato"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funzioni potenzial. limitate"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tocca per sbloccare"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dati utente bloccati"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profilo di lavoro bloccato"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tocca per sbloc. prof. di lav."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Connesso a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tocca per visualizzare i file"</string>
     <string name="pin_target" msgid="3052256031352291362">"Blocca"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 8337b2e..a67319c 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"גע להצגת עוד אפשרויות."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏ניפוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏גע כדי להשבית ניפוי באגים בהתקן ה-USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"האם לשתף את הדוח על הבאג עם מנהל המערכת?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"‏מנהל ה-IT ביקש דוח על באג כדי לסייע בפתרון בעיות"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"אישור"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"דחייה"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"עיבוד דוח על באג..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"גע כדי לבטל"</string>
     <string name="select_input_method" msgid="8547250819326693584">"שינוי מקלדת"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"בחר מקלדות"</string>
     <string name="show_ime" msgid="2506087537466597099">"השאר אותו במסך בזמן שהמקלדת הפיזית פעילה"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"‏הושבתה על ידי מנהל המערכת של %1$s. צור איתו קשר כדי לקבל מידע נוסף."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"יש לך הודעות חדשות"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"‏פתח את אפליקציית ה-SMS כדי להציג"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ייתכן שפונקציות מסוימות לא יהיו זמינות"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"גע כדי להמשיך"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"פרופיל המשתמש נעול"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ייתכן שחלק מהפונקציונליות תהיה מוגבלת"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"הקש כדי לבטל את הנעילה"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"נתוני משתמש נעולים"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"פרופיל העבודה נעול"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"הקש לביטול נעילת פרופיל העבודה"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"מחובר אל <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"הקש כדי להציג קבצים"</string>
     <string name="pin_target" msgid="3052256031352291362">"הצמד"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 237d779..166eca7 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1054,12 +1054,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"タップしてその他のオプションを表示"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効化"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"管理者とバグレポートを共有しますか?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT 管理者からトラブルシューティングに役立てるためバグレポートを共有するようリクエストがありました"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"同意する"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"同意しない"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"バグレポートを取得しています…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"キャンセルするにはタップしてください"</string>
     <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"キーボードの選択"</string>
     <string name="show_ime" msgid="2506087537466597099">"物理キーボードが有効になっている間は、画面に表示されます"</string>
@@ -1561,9 +1567,11 @@
     <skip />
     <string name="new_sms_notification_title" msgid="8442817549127555977">"新着メッセージがあります"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"表示するには SMS アプリを開きます"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"一部の機能が利用できない可能性"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"続行するにはタップしてください"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ユーザー プロフィールはロックされています"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"一部機能が制限されている可能性"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ロック解除するにはタップします"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ユーザーデータはロック状態です"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"仕事用プロファイル: ロック"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"タップしてプロファイルをロック解除"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> に接続しました"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"タップしてファイルを表示"</string>
     <string name="pin_target" msgid="3052256031352291362">"固定"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index fc11729..178e023 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"შეეხეთ დამატებითი პარამეტრებისთვის."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"გსურთ ხარვეზის შესახებ ანგარიშის ადმინისტრატორთან გაზიარება?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"პრობლემის აღმოფხვრაში დასახმარებლად, თქვენი IT ადმინისტრატორი ხარვეზის შესახებ ანგარიშს ითხოვს."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"მიღება"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"უარყოფა"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"შეეხეთ გასაუქმებლად"</string>
     <string name="select_input_method" msgid="8547250819326693584">"კლავიატურის შეცვლა"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"კლავიატურების არჩევა"</string>
     <string name="show_ime" msgid="2506087537466597099">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string>
@@ -1538,7 +1544,7 @@
       <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> შერჩეული</item>
     </plurals>
     <string name="default_notification_topic_label" msgid="227586145791870829">"სხვადასხვა"</string>
-    <string name="importance_from_topic" msgid="3572280439880023233">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრება თქვენ მიერ."</string>
+    <string name="importance_from_topic" msgid="3572280439880023233">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string>
     <string name="importance_from_person" msgid="9160133597262938296">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
     <string name="user_creation_account_exists" msgid="1942606193570143289">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს, <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას ?"</string>
     <string name="user_creation_adding" msgid="4482658054622099197">"მიეცეს უფლება <xliff:g id="APP">%1$s</xliff:g>-ს, <xliff:g id="ACCOUNT">%2$s</xliff:g>-ის მეშვეობით ახალი მომხმარებელი შექმნას (ამ ანგარიშის მქონე მომხმარებელი უკვე არსებობს) ?"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"გათიშულია „%1$s“-ის ადმინისტრატორის მიერ. დაუკავშირდით მას მეტის გასაგებად."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"თქვენ ახალი შეტყობინებები გაქვთ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"სანახავად, გახსენით SMS აპი"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ზოგიერთი ფუნქცია შეიძლება მიუწვდომელი იყოს"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"შეეხეთ გასაგრძელებლად"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"მომხმარებლის პროფილი ჩაკეტილია"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ზოგიერთი ფუნქცია შეიძლება შეიზღუდოს"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"შეეხეთ განსაბლოკად"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"მომხმ.-ის მონაცემები ჩაკეტილია"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"სამსახურის პროფილი ჩაკეტილია"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"შეეხეთ პროფილის განსაბლოკად"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"დაკავშირებულია <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-თან"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"შეეხეთ ფაილების სანახავად"</string>
     <string name="pin_target" msgid="3052256031352291362">"ჩამაგრება"</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 7e6025d..259278a 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Қосымша параметрлер үшін түртіңіз."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB жөндеуді өшіру үшін түртіңіз."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Қате туралы есепті әкімшімен бөлісу керек пе?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"АТ әкімшісі ақауларды жоюға көмектесу үшін қате туралы есепті сұрады"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ҚАБЫЛДАУ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ҚАБЫЛДАМАУ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Қате туралы есеп құрылуда…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Бас тарту үшін түртіңіз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Пернетақтаны өзгерту"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Пернетақталарды таңдау"</string>
     <string name="show_ime" msgid="2506087537466597099">"Физикалық пернетақта белсенді кезде оны экранда ұстау"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s әкімшісі өшірген. Қосымша мәліметтер алу үшін оларға хабарласыңыз."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Сізде жаңа хабарлар бар"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Көру үшін SMS қолданбасын ашыңыз"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Кейбір функциялар қол жетімді болмауы мүмкін"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Жалғастыру үшін түртіңіз"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Пайдаланушы профилі құлыпталған"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Кейбір функциялар істемеуі мүмкін"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Құлыпты ашу үшін түртіңіз"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Пайдаланушы деректері құлыптаулы"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Жұмыс профилі құлыптаулы"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Жұмыс профилінің құлпын ашу үшін түртіңіз"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> қосылу орындалды"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлдарды көру үшін түртіңіз"</string>
     <string name="pin_target" msgid="3052256031352291362">"PIN код"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 0ca72a7..7390b6b 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1055,12 +1055,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ប៉ះដើម្បីបានជម្រើសថែមទៀត។"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"បាន​ភ្ជាប់​ការ​កែ​កំហុស​យូអេសប៊ី"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បី​បិទ​ការ​កែ​កំហុស​យូអេសប៊ី។"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ចែករំលែករបាយការណ៍កំហុសជាមួយអ្នកគ្រប់គ្រងឬ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"អ្នកគ្រប់គ្រងព័ត៌មានវិទ្យារបស់អ្នកបានស្នើរបាយការណ៍កំហុសដើម្បីជួយដោះស្រាយបញ្ហា"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ព្រមទទួល"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"បដិសេធ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ទទួលយករបាយការណ៍កំហុស…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ប៉ះដើម្បីបោះបង់"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ប្ដូរ​ក្ដារចុច"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ជ្រើស​ក្ដារចុច"</string>
     <string name="show_ime" msgid="2506087537466597099">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string>
@@ -1557,9 +1563,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"បិទដំណើរការដោយអ្នកគ្រប់គ្រង %1$s។ សូមទាក់ទងពួកគេដើម្បីស្វែងយល់បន្ថែម។"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"អ្នកមានសារថ្មី"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"បើកកម្មវិធីសារ SMS ដើម្បីមើល"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"មុខងារមួយចំនួនមិនអាចប្រើបានទេ"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ប៉ះដើម្បីបន្ត"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ប្រវត្តិរូបអ្នកប្រើត្រូវបានចាក់សោ"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"លទ្ធភាពប្រើមុខងារមួយចំនួនអាចត្រូវបាកម្រិត"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ប៉ះដើម្បីដោះសោ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ទិន្នន័យអ្នកប្រើជាប់សោ"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ប្រវត្តិរូបការងារត្រូវជាប់សោ"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ប៉ះដើម្បីដោះសោប្រវត្តិរូបការងារ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"បានភ្ជាប់ទៅ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ប៉ះដើម្បីមើលឯកសារ"</string>
     <string name="pin_target" msgid="3052256031352291362">"ខ្ទាស់"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index d251f82..ff1d028 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಸ್ಪರ್ಶಿಸಿ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್‌‌ ಸಂಪರ್ಕ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗಿಂಗ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ದೋಷ ವರದಿಯನ್ನು ನಿರ್ವಾಹಕರ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳುವುದೇ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ನಿಮ್ಮ ಐಟಿ ನಿರ್ವಾಹಕರು ಸಮಸ್ಯೆ ನಿವಾರಣೆಗೆ ಸಹಾಯ ಮಾಡಲು ದೋಷ ವರದಿಯನ್ನು ಮನವಿ ಮಾಡಿದ್ದಾರೆ"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ಸಮ್ಮತಿಸು"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ತಿರಸ್ಕರಿಸು"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ರದ್ದುಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ಕೀಬೋರ್ಡ್‌ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="show_ime" msgid="2506087537466597099">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲೆ ಇರಿಸಿಕೊಳ್ಳಿ"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s ನಿರ್ವಾಹಕರಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಲು ಅವರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"ನೀವು ಹೊಸ ಸಂದೇಶಗಳನ್ನು ಹೊಂದಿರುವಿರಿ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"ವೀಕ್ಷಿಸಲು SMS ಅಪ್ಲಿಕೇಶನ್ ತೆರೆಯಿರಿ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ಕೆಲವು ಫಂಕ್ಷನ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲದಿರಬಹುದು"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ಮುಂದುವರಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ಬಳಕೆದಾರ ಪ್ರೊಫೈಲ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ಕೆಲವು ಕಾರ್ಯನಿರ್ವಹಣೆಗಳು ಸೀಮಿತವಾಗಿರಬಹುದು"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ಫೈಲ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ"</string>
     <string name="pin_target" msgid="3052256031352291362">"ಪಿನ್ ಮಾಡು"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index db8f5a6..bc0228a 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"더 많은 옵션을 확인하려면 터치하세요."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB 디버깅을 사용하지 않으려면 터치하세요."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"관리자와 버그 보고서를 공유하시겠습니까?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT 관리자가 문제해결을 위해 버그 보고서를 요청했습니다."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"수락"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"거절"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"버그 보고서 가져오는 중..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"취소하려면 터치하세요."</string>
     <string name="select_input_method" msgid="8547250819326693584">"키보드 변경"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"키보드 선택"</string>
     <string name="show_ime" msgid="2506087537466597099">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s 관리자에 의해 사용 중지되었습니다. 자세히 알아보려면 관리자에게 문의하세요."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"새 메시지 있음"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"SMS 앱을 열고 확인"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"일부 기능을 사용할 수 없음"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"계속하려면 터치하세요."</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"사용자 프로필이 잠겨 있습니다."</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"일부 기능이 제한될 수 있습니다."</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"잠금 해제하려면 탭하세요."</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"사용자 데이터 잠김"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"직장 프로필 잠김"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"탭하여 직장 프로필 잠금 해제"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>에 연결됨"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"파일을 확인하려면 탭하세요."</string>
     <string name="pin_target" msgid="3052256031352291362">"고정"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index d2d9ed1ff..5fc6a62 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1054,12 +1054,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Көбүрөөк параметр үчүн тийип коюңуз."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB мүчүлүштүктөрдү оңдоо туташтырылган"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB мүчүлүштүктөрдү жоюу мүмкүнчүлүгүн өчүрүү үчүн тийип коюңуз."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Администратор менен мүчүлүштүктөр тууралуу кабар бөлүшүлсүнбү?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT администраторуңуз мүчүлүштүктөр тууралуу маалыматты сурап жатат. Бул маалыматтын жардамы менен бузулган жерлерди аныктап, оңдоп берет."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"КАБЫЛ АЛУУ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ЧЕТКЕ КАГУУ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Мүчүлүштүк тууралуу кабар алынууда…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Жокко чыгаруу үчүн тийип коюңуз"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Баскычтопту өзгөртүү"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Баскычтопторду тандаңыз"</string>
     <string name="show_ime" msgid="2506087537466597099">"Баскычтоп иштетилгенде экранда көрүнүп турсун"</string>
@@ -1556,9 +1562,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s администратору тарабынан өчүрүлгөн. Көбүрөөк билүү үчүн администраторго кайрылыңыз."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Сизге жаңы билдирүүлөр келди"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Көрүү үчүн SMS колдонмосун ачыңыз"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Айрым функциялар иштбши мүмкн"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Улантуу үчүн тийип коюңуз"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Колдонуучнн профили кулпулнгн"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Айрым функциялар чектлши мүмкн"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Кулпусун ачуу үчүн таптаңыз"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Колдончнн дайындары кулпуланды"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Жумуш профили кулпуланган"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Таптап, жумуш профилин ачыңыз"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> менен туташты"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлдарды көрүү үчүн таптап коюңуз"</string>
     <string name="pin_target" msgid="3052256031352291362">"Кадоо"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index a52f957..0c146bd 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ສຳ​ພັດ​ສຳ​ລັບ​ທາງ​ເລືອກ​ເພີ່ມ​ເຕີມ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ເຊື່ອມຕໍ່ການດີບັ໊ກຜ່ານ USB ແລ້ວ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"ແຕະເພື່ອປິດການດີບັ໊ກຜ່ານ USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ແບ່ງປັນລາຍງານຂໍ້ຜິດພາດກັບຜູ້ເບິ່ງແຍງລະບົບບໍ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ຜູ້ເບິ່ງແຍງລະບົບໄອທີຂອງທ່ານໄດ້ຮ້ອງຂໍເອົາລາຍງານຂໍ້ຜິດພາດເພື່ອຊ່ວຍແກ້ໄຂບັນຫາ"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ຍອມຮັບ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ປະຕິເສດ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ກຳລັງເອົາລາຍງານຂໍ້ຜິດພາດ…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ແຕະເພື່ອຍົກເລີກ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"​ປ່ຽນ​ແປ້ນ​ພິມ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"​ເລືອກ​ແປ້ນ​ພິມ"</string>
     <string name="show_ime" msgid="2506087537466597099">"ເປີດໃຊ້ໃຫ້ມັນຢູ່ໃນໜ້າຈໍໃນຂະນະທີ່ໃຊ້ແປ້ນພິມພາຍນອກຢູ່"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"ຖືກປິດໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ %1$s. ກະລຸນາຕິດຕໍ່ຫາພວກເຂົາເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"ທ່ານມີຂໍ້ຄວາມໃໝ່"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"ເປີດແອັບ SMS ເພື່ອເບິ່ງ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ບາງຟັງຊັນອາດບໍ່ສາມາດໃຊ້ໄດ້"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ແຕະເພື່ອສືບຕໍ່"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ໂປຣໄຟລ໌ຜູ້ໃຊ້ຖືກລັອກໄວ້ແລ້ວ"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ບາງຄວາມສາມາດນຳໃຊ້ອາດຈະຖືກຈຳກັດ"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ແຕະເພື່ອປົດລັອກ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ລັອກຂໍ້ມູນຜູ້ໃຊ້ແລ້ວ"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຖືກລັອກ"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ແຕະເພື່ອປົດລັອກໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"ເຊື່ອມຕໍ່ກັບ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ແລ້ວ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ແຕະເພື່ອເບິ່ງໄຟລ໌"</string>
     <string name="pin_target" msgid="3052256031352291362">"ປັກໝຸດ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index e8759d7..e4d10ae 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Palieskite, kad būtų rodoma daugiau parinkčių."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Neleisti USB derinimo."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bendrinti pranešimą apie riktą su administratoriumi?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jūsų IT administratorius pateikė pranešimo apie riktą užklausą, kad galėtų padėti pašalinti triktis"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SUTIKTI"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ATMESTI"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Pateikiamas pranešimas apie riktą…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Palieskite, kad atšauktumėte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviatūros keitimas"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pasirinkti klaviatūras"</string>
     <string name="show_ime" msgid="2506087537466597099">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Išjungė %1$s administratorius. Kad sužinotumėte daugiau, susisiekite su juo."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Turite naujų pranešimų"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Atidaryti SMS programą, norint peržiūrėti"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Kelios funkc. gali būti nepas."</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Jei norite tęsti, palieskite"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Naudotojo profilis užrakintas"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Kai kurios funkcijos gali būti ribojamos"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Palieskite, kad atrakintumėte"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Naudotojo duomenys užrakinti"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Darbo profilis užrakintas"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Paliesk., kad atr. darbo prof."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Prisijungta prie „<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>“"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Palieskite, kad peržiūrėtumėte failus"</string>
     <string name="pin_target" msgid="3052256031352291362">"Prisegti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 81028f5..2fda60c 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1061,12 +1061,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Citas opcijas"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Iespējot USB atkļūdošanu."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vai kopīgot kļūdas pārskatu ar administratoru?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Jūsu IT administrators pieprasīja kļūdas pārskatu, lai palīdzētu novērst problēmu."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"APSTIPRINĀT"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"NORAIDĪT"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Notiek kļūdas pārskata izveide…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pieskarieties, lai atceltu"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tastatūras maiņa"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izvēlēties tastatūru"</string>
     <string name="show_ime" msgid="2506087537466597099">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string>
@@ -1574,9 +1580,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Atspējoja %1$s administrators. Lai uzzinātu vairāk, sazinieties ar administratoru."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Jums ir jaunas īsziņas."</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Lai skatītu, atveriet īsziņu lietotni."</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Dažas funkcijas var nebūt pieejamas"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Pieskarieties, lai turpinātu."</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Lietotāja profils ir bloķēts."</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Funkcijas var būt ierobežotas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Pieskarieties, lai atbloķētu."</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Lietotāja dati ir bloķēti."</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Darba profils ir bloķēts."</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Pieskarieties, lai atbloķētu."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Izveidots savienojums ar: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Pieskarieties, lai skatītu failus."</string>
     <string name="pin_target" msgid="3052256031352291362">"Piespraust"</string>
diff --git a/core/res/res/values-mcc310-mnc160-af/strings.xml b/core/res/res/values-mcc310-mnc160-af/strings.xml
new file mode 100644
index 0000000..72ca2f2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-af/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registreer by jou diensverskaffer"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-oproep"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-am/strings.xml b/core/res/res/values-mcc310-mnc160-am/strings.xml
new file mode 100644
index 0000000..5a6635c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-am/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ ይጠይቁ። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"የ%s Wi-Fi ጥሪ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ar/strings.xml b/core/res/res/values-mcc310-mnc160-ar/strings.xml
new file mode 100644
index 0000000..c0e4229
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذا الجهاز، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-az-rAZ/strings.xml b/core/res/res/values-mcc310-mnc160-az-rAZ/strings.xml
new file mode 100644
index 0000000..0c250cd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-az-rAZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Operatorla qeydiyyatdan keçin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Zəngi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..d351d5e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-b+sr+Latn/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrujte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi pozivanje preko operatera %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-bg/strings.xml b/core/res/res/values-mcc310-mnc160-bg/strings.xml
new file mode 100644
index 0000000..88715f5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-bg/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Регистриране с оператора ви"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s – обаждания през Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-bn-rBD/strings.xml b/core/res/res/values-mcc310-mnc160-bn-rBD/strings.xml
new file mode 100644
index 0000000..0c3e816
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-bn-rBD/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"আপনার পরিষেবা প্রদানকারীকে নথিভুক্ত করুন"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi কলিং"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ca/strings.xml b/core/res/res/values-mcc310-mnc160-ca/strings.xml
new file mode 100644
index 0000000..89baf1b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ca/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registra\'t amb el teu operador de telefonia mòbil"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Trucada per Wi-Fi amb %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-cs/strings.xml b/core/res/res/values-mcc310-mnc160-cs/strings.xml
new file mode 100644
index 0000000..3eb962e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrace u operátora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Volání přes Wi-Fi: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-da/strings.xml b/core/res/res/values-mcc310-mnc160-da/strings.xml
new file mode 100644
index 0000000..8e401d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Hvis du vil foretage opkald og sende beskeder via Wi-Fi, skal du først anmode dit mobilselskab om at konfigurere denne tjeneste. Derefter skal du slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrer dig hos dit mobilselskab"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-opkald"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-de/strings.xml b/core/res/res/values-mcc310-mnc160-de/strings.xml
new file mode 100644
index 0000000..7b172d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann erneut über die Einstellungen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registriere dich bei deinem Mobilfunkanbieter."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Anrufe über WLAN"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-el/strings.xml b/core/res/res/values-mcc310-mnc160-el/strings.xml
new file mode 100644
index 0000000..bfd09c0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία κλήσεων μέσω Wi-Fi από τις Ρυθμίσεις."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Κλήση Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc160-en-rAU/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rAU/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml
new file mode 100644
index 0000000..d4f59ed
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"To make calls and send messages over Wi-Fi, first ask your carrier to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml
new file mode 100644
index 0000000..8930a3e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para realizar llamadas o enviar mensajes por Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar las llamadas por Wi-Fi desde Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regístrate con tu proveedor."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Llamada por Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-es/strings.xml b/core/res/res/values-mcc310-mnc160-es/strings.xml
new file mode 100644
index 0000000..1aac00b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para hacer llamadas y enviar mensajes por Wi-Fi, debes pedir antes a tu operador que configure este servicio. Una vez hecho esto, vuelva a activar las llamadas Wi-Fi en Ajustes."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regístrate con tu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Llamada Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml b/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
new file mode 100644
index 0000000..c3be115
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-et-rEE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registreeruge operaatori juures"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Operaatori %s WiFi-kõned"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml b/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml
new file mode 100644
index 0000000..93c4026
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-eu-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Erregistratu operadorearekin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi bidezko deiak"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fa/strings.xml b/core/res/res/values-mcc310-mnc160-fa/strings.xml
new file mode 100644
index 0000000..247693a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fa/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره از تنظیمات، تماس Wi-Fi را روشن کنید."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ثبت نام با شرکت مخابراتی شما"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"‏تماس ‪%s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fi/strings.xml b/core/res/res/values-mcc310-mnc160-fi/strings.xml
new file mode 100644
index 0000000..aebdf71
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi-puhelut: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml
new file mode 100644
index 0000000..b0d21c2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-fr/strings.xml b/core/res/res/values-mcc310-mnc160-fr/strings.xml
new file mode 100644
index 0000000..9fe787c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Pour effectuer des appels et envoyer des messages via le Wi-Fi, demandez tout d\'abord à votre opérateur de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Inscrivez-vous auprès de votre opérateur."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml b/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
new file mode 100644
index 0000000..f02d667
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-gl-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas por wifi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Rexístrate co teu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas por wifi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml
new file mode 100644
index 0000000..e218ee6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-gu-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi કૉલિંગ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hi/strings.xml b/core/res/res/values-mcc310-mnc160-hi/strings.xml
new file mode 100644
index 0000000..23f4dc8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"अपने वाहक के साथ पंजीकृत करें"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s वाई-फ़ाई कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hr/strings.xml b/core/res/res/values-mcc310-mnc160-hr/strings.xml
new file mode 100644
index 0000000..956093a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Da biste telefonirali i slali pozive putem Wi-Fi-ja, morate tražiti od mobilnog operatera da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u Postavkama."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrirajte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi pozivanje"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hu/strings.xml b/core/res/res/values-mcc310-mnc160-hu/strings.xml
new file mode 100644
index 0000000..7dbf9e8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Ha Wi-Fin szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regisztráljon szolgáltatójánál"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-hívás"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-hy-rAM/strings.xml b/core/res/res/values-mcc310-mnc160-hy-rAM/strings.xml
new file mode 100644
index 0000000..aadc509
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-hy-rAM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Գրանցվեք օպերատորի մոտ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi զանգեր"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-in/strings.xml b/core/res/res/values-mcc310-mnc160-in/strings.xml
new file mode 100644
index 0000000..3640291
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-in/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Harap daftarkan ke operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Panggilan Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml b/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml
new file mode 100644
index 0000000..fd10da5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-is-rIS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Skráðu þig hjá símafyrirtækinu"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi símtöl"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-it/strings.xml b/core/res/res/values-mcc310-mnc160-it/strings.xml
new file mode 100644
index 0000000..d8479d3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Per poter effettuare chiamate e inviare messaggi tramite Wi-Fi, devi chiedere all\'operatore di attivare il servizio. Dopodiché, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrati con il tuo operatore"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chiamate Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-iw/strings.xml b/core/res/res/values-mcc310-mnc160-iw/strings.xml
new file mode 100644
index 0000000..2aa3937
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-iw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב התקשרות Wi-Fi מ\'הגדרות\'."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"הירשם אצל הספק"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"‏שיחות Wi-Fi של %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ja/strings.xml b/core/res/res/values-mcc310-mnc160-ja/strings.xml
new file mode 100644
index 0000000..e589334
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社にWi-Fiサービスを申し込んだ上で、設定画面でWi-Fi発信を再度ONにしてください。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"携帯通信会社に登録してください"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi通話(%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml b/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml
new file mode 100644
index 0000000..2b8fd07
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ka-rGE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi-ს მეშვეობით ზარების განხორციელების ან შეტყობინების გაგზავნისათვის, პირველ რიგში დაეკითხეთ თქვენს ოპერატორს აღნიშნულ მომსახურებაზე. შემდეგ ხელახლა ჩართეთ Wi-Fi ზარები პარამეტრებიდან."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"დაარეგისტრირეთ თქვენი ოპერატორი"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s დარეკვა Wi-Fi-ს მეშვეობით"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-kk-rKZ/strings.xml b/core/res/res/values-mcc310-mnc160-kk-rKZ/strings.xml
new file mode 100644
index 0000000..b4f2433
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-kk-rKZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін Параметрлерден Wi-Fi қоңырау шалуын іске қосыңыз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Жабдықтаушыңыз арқылы тіркелу"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi арқылы қоңырау шалу"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-km-rKH/strings.xml b/core/res/res/values-mcc310-mnc160-km-rKH/strings.xml
new file mode 100644
index 0000000..1806fbc
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-km-rKH/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"ការហៅតាមរយៈ Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml
new file mode 100644
index 0000000..43d942a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-kn-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ Wi-Fi ಆನ್‌ ಮಾಡಿ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ko/strings.xml b/core/res/res/values-mcc310-mnc160-ko/strings.xml
new file mode 100644
index 0000000..9e13223
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"이동통신사에 등록"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi 통화"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
new file mode 100644
index 0000000..8b88ac1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ky-rKG/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде байланыш операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Операторуңузга катталыңыз"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi чалуу"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-lo-rLA/strings.xml b/core/res/res/values-mcc310-mnc160-lo-rLA/strings.xml
new file mode 100644
index 0000000..a5347a9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lo-rLA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"ເພື່ອ​ໂທ ແລະ​ສົ່ງ​ຂໍ້​ຄວາມ​ຢູ່​ເທິງ Wi-Fi, ກ່ອນ​ອື່ນ​ໝົດ​ໃຫ້​ຖ້າມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ ເພື່ອ​ຕັ້ງ​ການ​ບໍ​ລິ​ການ​ນີ້. ຈາກນັ້ນ​ເປີດການ​ໂທ Wi-Fi ອີກ​ຈາກ​ການ​ຕັ້ງ​ຄ່າ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ລົງ​ທະ​ບຽນ​ກັບ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເຄືອ​ຂ່າຍ​ຂອງ​ທ່ານ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"ການ​ໂທ %s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-lt/strings.xml b/core/res/res/values-mcc310-mnc160-lt/strings.xml
new file mode 100644
index 0000000..81b7488
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Jei norite skambinti ir siųsti pranešimus „Wi-Fi“ ryšiu, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite skambinimą „Wi-Fi“ ryšiu „Nustatymų“ skiltyje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Užregistruokite pas operatorių"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"„%s“ „Wi-Fi“ skambinimas"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-lv/strings.xml b/core/res/res/values-mcc310-mnc160-lv/strings.xml
new file mode 100644
index 0000000..5d24c5f
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-lv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoru iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Reģistrēt to pie sava mobilo sakaru operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi zvani"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml b/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml
new file mode 100644
index 0000000..aea280e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mk-rMK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете повикување преку Wi-Fi во Поставки."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Регистрирајте се со операторот"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Повикување преку Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ml-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-ml-rIN/strings.xml
new file mode 100644
index 0000000..9e244eb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ml-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s വൈഫൈ കോളിംഗ്"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml b/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml
new file mode 100644
index 0000000..5b59d99
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mn-rMN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi-аар дуудлага хийх болон мессеж илгээхээр бол эхлээд оператороосоо энэ төхөөрөмжийг тохируулж өгөхийг хүсээрэй. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаагаарай."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Операторт бүртгүүлэх"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi Дуудлага"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-mr-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-mr-rIN/strings.xml
new file mode 100644
index 0000000..168c36b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-mr-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"आपल्या वाहकासह नोंदणी करा"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s वाय-फाय कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml b/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
new file mode 100644
index 0000000..74bd9d6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ms-rMY/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda menyediakan perkhidmatan ini. Kemudian hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Daftar dengan pembawa anda"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml b/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml
new file mode 100644
index 0000000..ae87ae7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-my-rMM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"ဝိုင်ဖိုင်သုံး၍ ဖုန်းခေါ်ဆိုရန်နှင့် မက်စေ့ဂျ်များပို့ရန်၊ ဤဝန်ဆောင်မှုအား စတင်သုံးနိုင်ရန်အတွက် သင့် မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးမြန်းပါ။ ထို့နောက် ဆက်တင်မှတဆင့် ဝိုင်ဖိုင် ခေါ်ဆိုမှုအား ထပ်ဖွင့်ပါ။"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"သင့် မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s ဝိုင်ဖိုင် ခေါ်ဆိုမှု"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-nb/strings.xml b/core/res/res/values-mcc310-mnc160-nb/strings.xml
new file mode 100644
index 0000000..34357e1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"For å ringe og sende meldinger over Wi-Fi må du først be operatøren om å konfigurere denne tjenesten. Deretter slår du på Wi-Fi-anrop igjen fra Innstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrer deg hos operatøren din"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-anrop"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml b/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
new file mode 100644
index 0000000..8956249
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ne-rNP/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi बाट कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"आफ्नो वाहकसँग दर्ता गर्नुहोस्"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi कलिङ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-nl/strings.xml b/core/res/res/values-mcc310-mnc160-nl/strings.xml
new file mode 100644
index 0000000..319f799
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via \'Instellingen\'."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registreren bij je provider"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Bellen via wifi van %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml
new file mode 100644
index 0000000..5641abe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pa-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈਟ ਅਪ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਵਿੱਚੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pl/strings.xml b/core/res/res/values-mcc310-mnc160-pl/strings.xml
new file mode 100644
index 0000000..1d916cb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Zarejestruj u operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Połączenia przez Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml
new file mode 100644
index 0000000..1c68cb1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt-rBR/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
new file mode 100644
index 0000000..86dba8c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar este serviço. Em seguida, nas Definições, ative novamente as Chamadas Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registar-se junto do seu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Chamadas Wi-Fi da %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-pt/strings.xml b/core/res/res/values-mcc310-mnc160-pt/strings.xml
new file mode 100644
index 0000000..1c68cb1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ro/strings.xml b/core/res/res/values-mcc310-mnc160-ro/strings.xml
new file mode 100644
index 0000000..f2490d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ro/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Înregistrați-vă la operatorul dvs."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Apelare prin Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ru/strings.xml b/core/res/res/values-mcc310-mnc160-ru/strings.xml
new file mode 100644
index 0000000..9f2bc43
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Укажите оператора и зарегистрируйтесь"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Звонки по Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml b/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml
new file mode 100644
index 0000000..0c13341
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-si-rLK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi අමතමින්"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sk/strings.xml b/core/res/res/values-mcc310-mnc160-sk/strings.xml
new file mode 100644
index 0000000..3fe32f7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrujte sa so svojím operátorom"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Volanie siete Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sl/strings.xml b/core/res/res/values-mcc310-mnc160-sl/strings.xml
new file mode 100644
index 0000000..3818309
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registracija pri operaterju"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Klicanje prek Wi-Fi-ja (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml b/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml
new file mode 100644
index 0000000..647cd03
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sq-rAL/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Regjistrohu me operatorin tënd celular"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Telefonatat me Wi-Fi nga %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sr/strings.xml b/core/res/res/values-mcc310-mnc160-sr/strings.xml
new file mode 100644
index 0000000..7f8381a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Региструјте се код мобилног оператера"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Wi-Fi позивање преко оператера %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sv/strings.xml b/core/res/res/values-mcc310-mnc160-sv/strings.xml
new file mode 100644
index 0000000..e72b3b7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Registrera dig hos operatören"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi-samtal"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-sw/strings.xml b/core/res/res/values-mcc310-mnc160-sw/strings.xml
new file mode 100644
index 0000000..08ee7536
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-sw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Jisajili na mtoa huduma wako"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Upigaji Simu kwa Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml
new file mode 100644
index 0000000..d6ea49c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ta-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s வைஃபை அழைப்பு"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml b/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml
new file mode 100644
index 0000000..61f3929
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-te-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fiలో కాల్‌లు చేయడం మరియు సందేశాలు పంపడం కోసం ముందుగా ఈ సేవను సెటప్ చేయడానికి మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి మళ్లీ Wi-Fi కాలింగ్‌ను ఆన్ చేయండి."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi కాలింగ్"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-th/strings.xml b/core/res/res/values-mcc310-mnc160-th/strings.xml
new file mode 100644
index 0000000..f1ff305
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-th/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"ลงทะเบียนกับผู้ให้บริการ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"กำลังเรียก Wi-Fi ของ %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-tl/strings.xml b/core/res/res/values-mcc310-mnc160-tl/strings.xml
new file mode 100644
index 0000000..380b410
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-tl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag gamit ang Wi-Fi mula sa Mga Setting."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Magparehistro sa iyong carrier"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Pagtawag Gamit ang Wi-Fi ng %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-tr/strings.xml b/core/res/res/values-mcc310-mnc160-tr/strings.xml
new file mode 100644
index 0000000..2cb1dc9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra tekrar Ayarlar\'dan Kablosuz çağrı özelliğini açın."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Operatörünüze kaydolun"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Kablosuz Çağrı"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-uk/strings.xml b/core/res/res/values-mcc310-mnc160-uk/strings.xml
new file mode 100644
index 0000000..9e4d94c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-uk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Зареєструйтеся в оператора"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Дзвінок через Wi-Fi від оператора %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml b/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml
new file mode 100644
index 0000000..e617582
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-ur-rPK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو ترتیب دینے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"‏‎%s Wi-Fi کالنگ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-uz-rUZ/strings.xml b/core/res/res/values-mcc310-mnc160-uz-rUZ/strings.xml
new file mode 100644
index 0000000..a951fc4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-uz-rUZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi qo‘ng‘iroqlar"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-vi/strings.xml b/core/res/res/values-mcc310-mnc160-vi/strings.xml
new file mode 100644
index 0000000..8f68be6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-vi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại Gọi qua Wi-Fi từ Cài đặt."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"Gọi qua Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml
new file mode 100644
index 0000000..3b10a63
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"向您的运营商注册"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s WLAN 通话功能"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml
new file mode 100644
index 0000000..a39b37c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先向您的流動網絡供應商要求設定此服務。然後再次在「設定」中開啟 Wi-Fi 通話。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"向您的流動網絡供應商註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc160-zh-rTW/strings.xml
new file mode 100644
index 0000000..28690aa
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"如要透過 Wi-FI 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"向您的行動通訊業者註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc160-zu/strings.xml b/core/res/res/values-mcc310-mnc160-zu/strings.xml
new file mode 100644
index 0000000..d08486d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc160-zu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="3017901214286816293">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="7068215934335709161">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="2031160810542298336">"%s ukushaya kwe-Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-af/strings.xml b/core/res/res/values-mcc310-mnc200-af/strings.xml
new file mode 100644
index 0000000..22d2685
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-af/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registreer by jou diensverskaffer"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s-Wi-Fi-oproepe"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-am/strings.xml b/core/res/res/values-mcc310-mnc200-am/strings.xml
new file mode 100644
index 0000000..6592d18
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-am/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ ይጠይቁ። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"የ%s Wi-Fi ጥሪ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ar/strings.xml b/core/res/res/values-mcc310-mnc200-ar/strings.xml
new file mode 100644
index 0000000..ca411f6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-az-rAZ/strings.xml b/core/res/res/values-mcc310-mnc200-az-rAZ/strings.xml
new file mode 100644
index 0000000..94e7f88
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-az-rAZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Operatorla qeydiyyatdan keçin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi Zəngi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc200-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..3dc4fff
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-b+sr+Latn/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrujte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Wi-Fi pozivanje preko operatera %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-bg/strings.xml b/core/res/res/values-mcc310-mnc200-bg/strings.xml
new file mode 100644
index 0000000..b190b7d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-bg/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Регистриране с оператора ви"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s – обаждания през Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-bn-rBD/strings.xml b/core/res/res/values-mcc310-mnc200-bn-rBD/strings.xml
new file mode 100644
index 0000000..26d6156
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-bn-rBD/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"আপনার পরিষেবা প্রদানকারীর সাথে নথিভুক্ত করুন"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi কলিং"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-bs-rBA/strings.xml b/core/res/res/values-mcc310-mnc200-bs-rBA/strings.xml
new file mode 100644
index 0000000..d9913af
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-bs-rBA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrirajte se kod operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi pozivanje"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ca/strings.xml b/core/res/res/values-mcc310-mnc200-ca/strings.xml
new file mode 100644
index 0000000..17e9a96
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ca/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registra\'t amb el teu operador de telefonia mòbil"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Trucades per Wi-Fi amb %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-cs/strings.xml b/core/res/res/values-mcc310-mnc200-cs/strings.xml
new file mode 100644
index 0000000..edfd91e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrace u operátora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Volání přes Wi-Fi: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-da/strings.xml b/core/res/res/values-mcc310-mnc200-da/strings.xml
new file mode 100644
index 0000000..4fa58c9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Før du kan foretage opkald og sende beskeder via Wi-Fi, skal du anmode dit mobilselskab om at konfigurere denne tjeneste. Du skal derefter slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrer dig hos dit mobilselskab"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi-opkald"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-de/strings.xml b/core/res/res/values-mcc310-mnc200-de/strings.xml
new file mode 100644
index 0000000..83fca41
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registriere dich bei deinem Mobilfunkanbieter"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s-WLAN-Anrufe"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-el/strings.xml b/core/res/res/values-mcc310-mnc200-el/strings.xml
new file mode 100644
index 0000000..3e01614
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας που χρησιμοποιείτε να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία Κλήσης Wi-Fi από τις Ρυθμίσεις."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Κλήση Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc200-en-rAU/strings.xml
new file mode 100644
index 0000000..78d5efe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-en-rAU/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc200-en-rGB/strings.xml
new file mode 100644
index 0000000..78d5efe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-en-rIN/strings.xml
new file mode 100644
index 0000000..78d5efe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc200-es-rUS/strings.xml
new file mode 100644
index 0000000..f7e80c3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para realizar llamadas y enviar mensajes con Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar Llamada con Wi-Fi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Regístrate con tu proveedor"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Llamada con Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-es/strings.xml b/core/res/res/values-mcc310-mnc200-es/strings.xml
new file mode 100644
index 0000000..9ec401a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para hacer llamadas y enviar mensajes por Wi-Fi, solicita a tu operador que configure este servicio y, cuando lo haga, vuelve a activar las llamadas por Wi-Fi en Ajustes."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Regístrate con tu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Llamada por Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-et-rEE/strings.xml b/core/res/res/values-mcc310-mnc200-et-rEE/strings.xml
new file mode 100644
index 0000000..0635966
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-et-rEE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registreeruge operaatori juures"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Operaatori %s WiFi-kõned"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-eu-rES/strings.xml b/core/res/res/values-mcc310-mnc200-eu-rES/strings.xml
new file mode 100644
index 0000000..5f8d8dc
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-eu-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Erregistratu operadorearekin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi bidezko deiak"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-fa/strings.xml b/core/res/res/values-mcc310-mnc200-fa/strings.xml
new file mode 100644
index 0000000..698e254
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-fa/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره در «تنظیمات»، تماس از طریق Wi-Fi را روشن کنید."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"از طریق شرکت مخابراتی‌تان ثبت‌نام کنید"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"‏تماس از طریق ‪%s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-fi/strings.xml b/core/res/res/values-mcc310-mnc200-fi/strings.xml
new file mode 100644
index 0000000..d011bd5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-fi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Wi-Fi-puhelut: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc200-fr-rCA/strings.xml
new file mode 100644
index 0000000..c69de43
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-fr/strings.xml b/core/res/res/values-mcc310-mnc200-fr/strings.xml
new file mode 100644
index 0000000..cbc6d38
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Inscrivez-vous auprès de votre opérateur."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-gl-rES/strings.xml b/core/res/res/values-mcc310-mnc200-gl-rES/strings.xml
new file mode 100644
index 0000000..1736d77
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-gl-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas por wifi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Rexístrate co teu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Chamadas por wifi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-gu-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-gu-rIN/strings.xml
new file mode 100644
index 0000000..a78ed0d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-gu-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi કૉલિંગ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-hi/strings.xml b/core/res/res/values-mcc310-mnc200-hi/strings.xml
new file mode 100644
index 0000000..1d8272a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-hi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"अपने वाहक के साथ पंजीकृत करें"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s वाई-फ़ाई कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-hr/strings.xml b/core/res/res/values-mcc310-mnc200-hr/strings.xml
new file mode 100644
index 0000000..7977d96
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-hr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrirajte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi pozivi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-hu/strings.xml b/core/res/res/values-mcc310-mnc200-hu/strings.xml
new file mode 100644
index 0000000..daaf4f1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-hu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Ha Wi-Fin szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Regisztráljon szolgáltatójánál"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi-hívás"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-hy-rAM/strings.xml b/core/res/res/values-mcc310-mnc200-hy-rAM/strings.xml
new file mode 100644
index 0000000..36040e9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-hy-rAM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Գրանցվեք օպերատորի մոտ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi զանգեր"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-in/strings.xml b/core/res/res/values-mcc310-mnc200-in/strings.xml
new file mode 100644
index 0000000..c71dbf7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-in/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Harap daftarkan ke operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-is-rIS/strings.xml b/core/res/res/values-mcc310-mnc200-is-rIS/strings.xml
new file mode 100644
index 0000000..8c66836
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-is-rIS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Skráðu þig hjá símafyrirtækinu"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi símtöl"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-it/strings.xml b/core/res/res/values-mcc310-mnc200-it/strings.xml
new file mode 100644
index 0000000..cec5d8b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Per poter effettuare chiamate e inviare messaggi tramite Wi-Fi, devi chiedere all\'operatore di attivare il servizio. Dopodiché, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrati con il tuo operatore"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Chiamate Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-iw/strings.xml b/core/res/res/values-mcc310-mnc200-iw/strings.xml
new file mode 100644
index 0000000..c409606
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-iw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"הירשם אצל הספק"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"‏שיחות Wi-Fi של %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ja/strings.xml b/core/res/res/values-mcc310-mnc200-ja/strings.xml
new file mode 100644
index 0000000..0486812
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"携帯通信会社に登録してください"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Wi-Fi 通話(%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ka-rGE/strings.xml b/core/res/res/values-mcc310-mnc200-ka-rGE/strings.xml
new file mode 100644
index 0000000..cb1734a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ka-rGE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"დარეგისტრირდით თქვენი ოპერატორის მეშვეობით"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Wi-Fi დარეკვა (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-kk-rKZ/strings.xml b/core/res/res/values-mcc310-mnc200-kk-rKZ/strings.xml
new file mode 100644
index 0000000..a7ba1f1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-kk-rKZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін \"Параметрлер\" тармағында Wi-Fi қоңырауларын қосыңыз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Оператор арқылы тіркелу"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi қоңыраулары"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-km-rKH/strings.xml b/core/res/res/values-mcc310-mnc200-km-rKH/strings.xml
new file mode 100644
index 0000000..a0871a8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-km-rKH/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"ការហៅតាមរយៈ Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-kn-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-kn-rIN/strings.xml
new file mode 100644
index 0000000..4428f82
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-kn-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್‌ ಮಾಡಿ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ko/strings.xml b/core/res/res/values-mcc310-mnc200-ko/strings.xml
new file mode 100644
index 0000000..b42cc05
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"이동통신사에 등록"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi 통화"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc200-ky-rKG/strings.xml
new file mode 100644
index 0000000..896afde
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ky-rKG/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Операторуңузга катталыңыз"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi чалуу"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-lo-rLA/strings.xml b/core/res/res/values-mcc310-mnc200-lo-rLA/strings.xml
new file mode 100644
index 0000000..4476900
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-lo-rLA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານເພື່ອຕັ້ງບໍລິການນີ້ກ່ອນ. ຈາກນັ້ນ ເປີດການໂທ Wi-Fi ອີກເທື່ອໜຶ່ງຈາກການຕັ້ງຄ່າ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ລົງທະບຽນນໍາຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"ການໂທ %s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-lt/strings.xml b/core/res/res/values-mcc310-mnc200-lt/strings.xml
new file mode 100644
index 0000000..4fb0510
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-lt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą Nustatymų skiltyje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Užregistruokite pas operatorių"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"„%s“ „Wi-Fi“ skambinimas"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-lv/strings.xml b/core/res/res/values-mcc310-mnc200-lv/strings.xml
new file mode 100644
index 0000000..0471418
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-lv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Reģistrējieties pie sava mobilo sakaru operatora."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi zvani"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-mk-rMK/strings.xml b/core/res/res/values-mcc310-mnc200-mk-rMK/strings.xml
new file mode 100644
index 0000000..2582e2a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-mk-rMK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете Повици преку Wi-Fi во Поставки."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Регистрирајте се кај операторот"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Повици преку Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ml-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-ml-rIN/strings.xml
new file mode 100644
index 0000000..6bdde6d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ml-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s വൈഫൈ കോളിംഗ്"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-mn-rMN/strings.xml b/core/res/res/values-mcc310-mnc200-mn-rMN/strings.xml
new file mode 100644
index 0000000..0d24a34
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-mn-rMN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi дуудлага хийх болон зурвас илгээх бол эхлээд оператор компаниасаа энэ төхөөрөмжийг тохируулахыг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Оператор компанидаа бүртгүүлэх"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi Дуудлага"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-mr-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-mr-rIN/strings.xml
new file mode 100644
index 0000000..fc89cfc
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-mr-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"आपल्या वाहकासह नोंदणी करा"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s वाय-फाय कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ms-rMY/strings.xml b/core/res/res/values-mcc310-mnc200-ms-rMY/strings.xml
new file mode 100644
index 0000000..f658b8d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ms-rMY/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda menyediakan perkhidmatan ini. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Daftar dengan pembawa anda"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-my-rMM/strings.xml b/core/res/res/values-mcc310-mnc200-my-rMM/strings.xml
new file mode 100644
index 0000000..b91c2d0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-my-rMM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"ဝိုင်ဖိုင်ကိုအသုံးပြု၍ ဖုန်းခေါ်ဆိုရန်နှင့် စာပို့ရန်၊ ဤစက်ပစ္စည်းကို တပ်ဆင်ရန် သင့်အသုံးပြုသည့်မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးပါ။ ထို့နောက် ဆက်တင်များထဲမှ ဝိုင်ဖိုင်ခေါ်ဆိုမှုကို ဖွင့်ပါ။"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"သင့်အသုံးပြုသည့်မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s ဝိုင်ဖိုင်ခေါ်ဆိုမှု"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-nb/strings.xml b/core/res/res/values-mcc310-mnc200-nb/strings.xml
new file mode 100644
index 0000000..353da10
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Du må be operatøren din om å konfigurere denne tjenesten før du kan ringe og sende meldinger via Wi-Fi. Deretter slår du på Wi-Fi-anrop igjen fra innstillingene."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrer deg hos operatøren din"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi-anrop"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ne-rNP/strings.xml b/core/res/res/values-mcc310-mnc200-ne-rNP/strings.xml
new file mode 100644
index 0000000..5362798
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ne-rNP/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi मार्फत कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिले यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"तपाईंको वाहकसँगै दर्ता गर्नुहोस्"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi कलिङ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-nl/strings.xml b/core/res/res/values-mcc310-mnc200-nl/strings.xml
new file mode 100644
index 0000000..22f8de2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registreren bij je provider"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Bellen via wifi van %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-pa-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-pa-rIN/strings.xml
new file mode 100644
index 0000000..0083af3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-pa-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi \'ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈੱਟ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਤੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-pl/strings.xml b/core/res/res/values-mcc310-mnc200-pl/strings.xml
new file mode 100644
index 0000000..0ce774d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Zarejestruj u operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Połączenia przez Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc200-pt-rBR/strings.xml
new file mode 100644
index 0000000..23f3182
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-pt-rBR/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc200-pt-rPT/strings.xml
new file mode 100644
index 0000000..ff78c26
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar o serviço. Em seguida, nas Definições, ative novamente as Chamadas Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registar-se junto do seu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Chamadas Wi-Fi da %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-pt/strings.xml b/core/res/res/values-mcc310-mnc200-pt/strings.xml
new file mode 100644
index 0000000..23f3182
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ro/strings.xml b/core/res/res/values-mcc310-mnc200-ro/strings.xml
new file mode 100644
index 0000000..028a70b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ro/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Înregistrați-vă la operatorul dvs."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Apelare prin Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ru/strings.xml b/core/res/res/values-mcc310-mnc200-ru/strings.xml
new file mode 100644
index 0000000..23a4c34
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Укажите оператора и зарегистрируйтесь"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Звонки по Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-si-rLK/strings.xml b/core/res/res/values-mcc310-mnc200-si-rLK/strings.xml
new file mode 100644
index 0000000..f11ade3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-si-rLK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi අමතමින්"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sk/strings.xml b/core/res/res/values-mcc310-mnc200-sk/strings.xml
new file mode 100644
index 0000000..a64f9ec
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrujte sa so svojím operátorom"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Volanie cez Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sl/strings.xml b/core/res/res/values-mcc310-mnc200-sl/strings.xml
new file mode 100644
index 0000000..06c3d22
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registracija pri operaterju"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Klicanje prek omrežja Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sq-rAL/strings.xml b/core/res/res/values-mcc310-mnc200-sq-rAL/strings.xml
new file mode 100644
index 0000000..998d2fe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sq-rAL/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Regjistrohu me operatorin tënd celular"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Telefonatat me Wi-Fi nga %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sr/strings.xml b/core/res/res/values-mcc310-mnc200-sr/strings.xml
new file mode 100644
index 0000000..20e9946
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Региструјте се код мобилног оператера"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Wi-Fi позивање преко оператера %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sv/strings.xml b/core/res/res/values-mcc310-mnc200-sv/strings.xml
new file mode 100644
index 0000000..3302b93
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Registrera dig hos operatören"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi-samtal"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-sw/strings.xml b/core/res/res/values-mcc310-mnc200-sw/strings.xml
new file mode 100644
index 0000000..e53ca0b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-sw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Jisajili na mtoa huduma wako"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Upigaji Simu kwa Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ta-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-ta-rIN/strings.xml
new file mode 100644
index 0000000..49fecea
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ta-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s வைஃபை அழைப்பு"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-te-rIN/strings.xml b/core/res/res/values-mcc310-mnc200-te-rIN/strings.xml
new file mode 100644
index 0000000..85f29ee
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-te-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fiలో కాల్‌లు చేయడానికి మరియు సందేశాలు పంపడానికి, ముందుగా ఈ సేవను సెటప్ చేయమని మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి Wi-Fi కాలింగ్‌ను మళ్లీ ఆన్ చేయండి."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi కాలింగ్"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-th/strings.xml b/core/res/res/values-mcc310-mnc200-th/strings.xml
new file mode 100644
index 0000000..4758586
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-th/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"ลงทะเบียนกับผู้ให้บริการ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"การโทรผ่าน Wi-Fi ของ %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-tl/strings.xml b/core/res/res/values-mcc310-mnc200-tl/strings.xml
new file mode 100644
index 0000000..b7f41c7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-tl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Magparehistro sa iyong carrier"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Pagtawag Gamit ang Wi-Fi ng %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-tr/strings.xml b/core/res/res/values-mcc310-mnc200-tr/strings.xml
new file mode 100644
index 0000000..e104eb9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Operatörünüze kaydolun"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Kablosuz Çağrı"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-uk/strings.xml b/core/res/res/values-mcc310-mnc200-uk/strings.xml
new file mode 100644
index 0000000..3780843
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-uk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Зареєструйтеся в оператора"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Дзвінок через Wi-Fi від оператора %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-ur-rPK/strings.xml b/core/res/res/values-mcc310-mnc200-ur-rPK/strings.xml
new file mode 100644
index 0000000..5a2de77
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-ur-rPK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو سیٹ اپ کرنے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"‏‎%s ‏Wi-Fi کالنگ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-uz-rUZ/strings.xml b/core/res/res/values-mcc310-mnc200-uz-rUZ/strings.xml
new file mode 100644
index 0000000..5f0fefe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-uz-rUZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi qo‘ng‘iroqlar"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-vi/strings.xml b/core/res/res/values-mcc310-mnc200-vi/strings.xml
new file mode 100644
index 0000000..55b5c52
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-vi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"Gọi điện qua Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc200-zh-rCN/strings.xml
new file mode 100644
index 0000000..6c2a8d9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"向您的运营商注册"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s WLAN 通话功能"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc200-zh-rHK/strings.xml
new file mode 100644
index 0000000..61bd0a1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟 [Wi-Fi 通話]。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"向您的流動網絡供應商註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc200-zh-rTW/strings.xml
new file mode 100644
index 0000000..9658757
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"向您的行動通訊業者註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc200-zu/strings.xml b/core/res/res/values-mcc310-mnc200-zu/strings.xml
new file mode 100644
index 0000000..f4209a6
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc200-zu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="9107329079910661798">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2841003137832065541">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="6806975706640442517">"%s ukushaya kwe-Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-af/strings.xml b/core/res/res/values-mcc310-mnc210-af/strings.xml
new file mode 100644
index 0000000..7edb2bf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-af/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Om oproepe te maak en boodskappe oor Wi-Fi te stuur, vra jou diensverskaffer eers om hierdie diens op te stel. Skakel Wi-Fi-oproepe dan weer in Instellings aan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registreer by jou diensverskaffer"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s-Wi-Fi-oproepe"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-am/strings.xml b/core/res/res/values-mcc310-mnc210-am/strings.xml
new file mode 100644
index 0000000..9eb9324
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-am/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"በWi-Fi ላይ ጥሪዎችን ለማድረግ እና መልዕክቶችን ለመላክ መጀመሪያ የአገልግሎት አቅራቢዎ ይህን አገልግሎት እንዲያዘጋጅልዎ ይጠይቁ። ከዚያ ከቅንብሮች ሆነው እንደገና የWi-Fi ጥሪን ያብሩ።"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"የአገልግሎት አቅራቢዎ ጋር ይመዝገቡ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"የ%s Wi-Fi ጥሪ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ar/strings.xml b/core/res/res/values-mcc310-mnc210-ar/strings.xml
new file mode 100644
index 0000000..9d5893d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-az-rAZ/strings.xml b/core/res/res/values-mcc310-mnc210-az-rAZ/strings.xml
new file mode 100644
index 0000000..6a81835
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-az-rAZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi üzərindən zəng etmək və mesaj göndərmək üçün ilk öncə operatordan bu xidməti ayarlamağı tələb edin. Sonra Ayarlardan Wi-Fi çağrısını aktivləşdirin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Operatorla qeydiyyatdan keçin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi Zəngi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-b+sr+Latn/strings.xml b/core/res/res/values-mcc310-mnc210-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..dd43d61
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-b+sr+Latn/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Da biste upućivali pozive i slali poruke preko Wi-Fi-ja, prvo zatražite od mobilnog operatera da vam omogući ovu uslugu. Zatim u Podešavanjima ponovo uključite Pozivanje preko Wi-Fi-ja."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrujte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Wi-Fi pozivanje preko operatera %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-bg/strings.xml b/core/res/res/values-mcc310-mnc210-bg/strings.xml
new file mode 100644
index 0000000..b1ae65b
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-bg/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"За да извършвате обаждания и да изпращате съобщения през Wi-Fi, първо, помолете оператора си да настрои тази услуга. След това включете отново функцията за обаждания през Wi-Fi от настройките."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Регистриране с оператора ви"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s – обаждания през Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-bn-rBD/strings.xml b/core/res/res/values-mcc310-mnc210-bn-rBD/strings.xml
new file mode 100644
index 0000000..b4d000d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-bn-rBD/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi এর মাধ্যমে কল করতে ও বার্তা পাঠাতে, প্রথমে আপনার পরিষেবা প্রদানকারীকে এই পরিষেবার সেট আপ করার বিষয়ে জিজ্ঞাসা করুন। তারপরে আবার সেটিংস থেকে Wi-Fi কলিং চালু করুন।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"আপনার পরিষেবা প্রদানকারীর সাথে নথিভুক্ত করুন"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi কলিং"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-bs-rBA/strings.xml b/core/res/res/values-mcc310-mnc210-bs-rBA/strings.xml
new file mode 100644
index 0000000..c9ee9f7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-bs-rBA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Da biste pozivali i slali poruke preko Wi-Fi-ja, prvo zatražite od operatera da postavi tu uslugu. Potom u Postavkama ponovo uključite Wi-Fi pozivanje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrirajte se kod operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi pozivanje"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ca/strings.xml b/core/res/res/values-mcc310-mnc210-ca/strings.xml
new file mode 100644
index 0000000..aaa95cf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ca/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Per fer trucades i enviar missatges per Wi-Fi, primer has de demanar a l\'operador de telefonia mòbil que configuri aquest servei. Després, torna a activar les trucades per Wi-Fi des de Configuració."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registra\'t amb el teu operador de telefonia mòbil"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Trucades per Wi-Fi amb %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-cs/strings.xml b/core/res/res/values-mcc310-mnc210-cs/strings.xml
new file mode 100644
index 0000000..70c727e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrace u operátora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Volání přes Wi-Fi: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-da/strings.xml b/core/res/res/values-mcc310-mnc210-da/strings.xml
new file mode 100644
index 0000000..e50fec0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Før du kan foretage opkald og sende beskeder via Wi-Fi, skal du anmode dit mobilselskab om at konfigurere denne tjeneste. Du skal derefter slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrer dig hos dit mobilselskab"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi-opkald"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-de/strings.xml b/core/res/res/values-mcc310-mnc210-de/strings.xml
new file mode 100644
index 0000000..40be9d5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registriere dich bei deinem Mobilfunkanbieter"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s-WLAN-Anrufe"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-el/strings.xml b/core/res/res/values-mcc310-mnc210-el/strings.xml
new file mode 100644
index 0000000..18ebf12
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας που χρησιμοποιείτε να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία Κλήσης Wi-Fi από τις Ρυθμίσεις."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Κλήση Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-en-rAU/strings.xml b/core/res/res/values-mcc310-mnc210-en-rAU/strings.xml
new file mode 100644
index 0000000..ff31e92
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-en-rAU/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-en-rGB/strings.xml b/core/res/res/values-mcc310-mnc210-en-rGB/strings.xml
new file mode 100644
index 0000000..ff31e92
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-en-rGB/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-en-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-en-rIN/strings.xml
new file mode 100644
index 0000000..ff31e92
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-en-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"To make calls and send messages over Wi-Fi, first ask your operator to set up this service. Then turn on Wi-Fi calling again from Settings."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Register with your operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi Calling"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc210-es-rUS/strings.xml
new file mode 100644
index 0000000..86cbdf1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para realizar llamadas y enviar mensajes con Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar Llamada con Wi-Fi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Regístrate con tu proveedor"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Llamada con Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-es/strings.xml b/core/res/res/values-mcc310-mnc210-es/strings.xml
new file mode 100644
index 0000000..8fe5eba
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para hacer llamadas y enviar mensajes por Wi-Fi, solicita a tu operador que configure este servicio y, cuando lo haga, vuelve a activar las llamadas por Wi-Fi en Ajustes."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Regístrate con tu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Llamada por Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-et-rEE/strings.xml b/core/res/res/values-mcc310-mnc210-et-rEE/strings.xml
new file mode 100644
index 0000000..3da1866
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-et-rEE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"WiFi-võrgu kaudu helistamiseks ja sõnumite saatmiseks paluge operaatoril esmalt see teenus seadistada. Seejärel lülitage WiFi-kõned menüüs Seaded uuesti sisse."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registreeruge operaatori juures"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Operaatori %s WiFi-kõned"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-eu-rES/strings.xml b/core/res/res/values-mcc310-mnc210-eu-rES/strings.xml
new file mode 100644
index 0000000..b033231
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-eu-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi bidez deiak egiteko eta mezuak bidaltzeko, eskatu operadoreari zerbitzu hori gaitzeko. Ondoren, aktibatu Wi-Fi bidezko deiak Ezarpenak atalean."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Erregistratu operadorearekin"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi bidezko deiak"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-fa/strings.xml b/core/res/res/values-mcc310-mnc210-fa/strings.xml
new file mode 100644
index 0000000..8cb15f7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-fa/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"‏برای برقراری تماس و ارسال پیام از طریق Wi-Fi، ابتدا از شرکت مخابراتی‌تان درخواست کنید این سرویس را راه‌اندازی کند. سپس دوباره در «تنظیمات»، تماس از طریق Wi-Fi را روشن کنید."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"از طریق شرکت مخابراتی‌تان ثبت‌نام کنید"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"‏تماس از طریق ‪%s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-fi/strings.xml b/core/res/res/values-mcc310-mnc210-fi/strings.xml
new file mode 100644
index 0000000..b081845
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-fi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Jos haluat soittaa puheluita ja lähettää viestejä Wi-Fin kautta, pyydä ensin operaattoriasi ottamaan tämä palvelu käyttöön. Ota sitten Wi-Fi-puhelut käyttöön asetuksissa."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Rekisteröidy operaattorisi asiakkaaksi."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Wi-Fi-puhelut: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-fr-rCA/strings.xml b/core/res/res/values-mcc310-mnc210-fr-rCA/strings.xml
new file mode 100644
index 0000000..43d9d93
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-fr-rCA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Pour effectuer des appels et envoyer des messages par Wi-Fi, demandez tout d\'abord à votre fournisseur de services de configurer ce service. Réactivez ensuite les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Inscrivez-vous auprès de votre fournisseur de services"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-fr/strings.xml b/core/res/res/values-mcc310-mnc210-fr/strings.xml
new file mode 100644
index 0000000..6b3cacb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Inscrivez-vous auprès de votre opérateur."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-gl-rES/strings.xml b/core/res/res/values-mcc310-mnc210-gl-rES/strings.xml
new file mode 100644
index 0000000..fe2a326
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-gl-rES/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para facer chamadas e enviar mensaxes a través da wifi, primeiro pídelle ao teu operador que configure este servizo. A continuación, activa de novo as chamadas por wifi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Rexístrate co teu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Chamadas por wifi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-gu-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-gu-rIN/strings.xml
new file mode 100644
index 0000000..ccb4be4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-gu-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi પર કૉલ્સ કરવા અને સંદેશા મોકલવા માટે, પહેલા તમારા કેરીઅરને આ સેવા સેટ કરવા માટે કહો. પછી સેટિંગ્સમાંથી Wi-Fi કૉલિંગ ચાલુ કરો."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"તમારા કેરીઅર સાથે નોંધણી કરો"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi કૉલિંગ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-hi/strings.xml b/core/res/res/values-mcc310-mnc210-hi/strings.xml
new file mode 100644
index 0000000..b560f04
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-hi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"वाई-फ़ाई से कॉल करने और संदेश भेजने के लिए, सबसे पहले अपने वाहक से इस सेवा को सेट करने के लिए कहें. उसके बाद सेटिंग से पुन: वाई-फ़ाई कॉलिंग चालू करें."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"अपने वाहक के साथ पंजीकृत करें"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s वाई-फ़ाई कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-hr/strings.xml b/core/res/res/values-mcc310-mnc210-hr/strings.xml
new file mode 100644
index 0000000..caf5df9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-hr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Da biste telefonirali i slali poruke putem Wi-Fi-ja, od mobilnog operatera morate tražiti da vam postavi tu uslugu. Zatim ponovo uključite Wi-Fi pozive u postavkama."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrirajte se kod mobilnog operatera"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi pozivi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-hu/strings.xml b/core/res/res/values-mcc310-mnc210-hu/strings.xml
new file mode 100644
index 0000000..f7465a4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-hu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Ha Wi-Fin szeretne telefonálni és üzenetet küldeni, kérje meg szolgáltatóját, hogy állítsa be ezt a szolgáltatást. Ezután a Beállítások menüben kapcsolhatja be újra a Wi-Fi-hívást."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Regisztráljon szolgáltatójánál"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi-hívás"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-hy-rAM/strings.xml b/core/res/res/values-mcc310-mnc210-hy-rAM/strings.xml
new file mode 100644
index 0000000..69623ff
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-hy-rAM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi-ի միջոցով զանգեր կատարելու և հաղորդագրություններ ուղարկելու համար նախ դիմեք ձեր օպերատորին՝ ծառայությունը կարգավորելու համար: Ապա նորից միացրեք Wi-Fi զանգերը Կարգավորումներում:"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Գրանցվեք օպերատորի մոտ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi զանգեր"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-in/strings.xml b/core/res/res/values-mcc310-mnc210-in/strings.xml
new file mode 100644
index 0000000..264bb51
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-in/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Untuk melakukan panggilan telepon dan mengirim pesan melalui Wi-Fi, terlebih dahulu minta operator untuk menyiapkan layanan ini. Lalu, aktifkan lagi panggilan telepon Wi-Fi dari Setelan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Harap daftarkan ke operator"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-is-rIS/strings.xml b/core/res/res/values-mcc310-mnc210-is-rIS/strings.xml
new file mode 100644
index 0000000..f2433a0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-is-rIS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Til að hringja og senda skilaboð yfir Wi-Fi þarftu fyrst að biðja símafyrirtækið þitt um að setja þá þjónustu upp. Kveiktu síðan á Wi-Fi símtölum í stillingunum."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Skráðu þig hjá símafyrirtækinu"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi símtöl"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-it/strings.xml b/core/res/res/values-mcc310-mnc210-it/strings.xml
new file mode 100644
index 0000000..a307e4a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Per poter effettuare chiamate e inviare messaggi tramite Wi-Fi, devi chiedere all\'operatore di attivare il servizio. Dopodiché, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrati con il tuo operatore"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Chiamate Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-iw/strings.xml b/core/res/res/values-mcc310-mnc210-iw/strings.xml
new file mode 100644
index 0000000..4ecc513
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-iw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"‏כדי להתקשר ולשלוח הודעות ברשת Wi-Fi, תחילה יש לבקש מהספק להגדיר את השירות. לאחר מכן, יש להפעיל שוב שיחות Wi-Fi ב\'הגדרות\'."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"הירשם אצל הספק"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"‏שיחות Wi-Fi של %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ja/strings.xml b/core/res/res/values-mcc310-mnc210-ja/strings.xml
new file mode 100644
index 0000000..4cf6215
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"携帯通信会社に登録してください"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Wi-Fi 通話(%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ka-rGE/strings.xml b/core/res/res/values-mcc310-mnc210-ka-rGE/strings.xml
new file mode 100644
index 0000000..d12328c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ka-rGE/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi-ს მეშვეობით ზარების განსახორციელებლად ან შეტყობინებების გასაგზავნად, პირველ რიგში, ამ სერვისის გააქტიურება თქვენს ოპერატორს უნდა თხოვოთ. შემდეგ ხელახლა ჩართეთ Wi-Fi დარეკვა პარამეტრებიდან."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"დარეგისტრირდით თქვენი ოპერატორის მეშვეობით"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Wi-Fi დარეკვა (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-kk-rKZ/strings.xml b/core/res/res/values-mcc310-mnc210-kk-rKZ/strings.xml
new file mode 100644
index 0000000..cc6b022
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-kk-rKZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi арқылы қоңырау шалу және хабарларды жіберу үшін алдымен жабдықтаушыңыздан осы қызметті орнатуды сұраңыз. Содан кейін \"Параметрлер\" тармағында Wi-Fi қоңырауларын қосыңыз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Оператор арқылы тіркелу"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi қоңыраулары"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-km-rKH/strings.xml b/core/res/res/values-mcc310-mnc210-km-rKH/strings.xml
new file mode 100644
index 0000000..7a19737
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-km-rKH/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"ដើម្បីធ្វើការហៅ និងផ្ញើសារតាម Wi-Fi ដំបូងឡើយអ្នកត្រូវស្នើឲ្យក្រុមហ៊ុនរបស់អ្នកដំឡើងសេវាកម្មនេះសិន។ បន្ទាប់មកបើកការហៅតាម Wi-Fi ម្តងទៀតចេញពីការកំណត់។"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ចុះឈ្មោះជាមួយក្រុមហ៊ុនរបស់អ្នក"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"ការហៅតាមរយៈ Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-kn-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-kn-rIN/strings.xml
new file mode 100644
index 0000000..037ccda
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-kn-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್‌ ಮಾಡಿ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ko/strings.xml b/core/res/res/values-mcc310-mnc210-ko/strings.xml
new file mode 100644
index 0000000..c278352
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"이동통신사에 등록"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi 통화"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ky-rKG/strings.xml b/core/res/res/values-mcc310-mnc210-ky-rKG/strings.xml
new file mode 100644
index 0000000..1dce9c4
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ky-rKG/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi аркылуу чалууларды аткарып жана билдирүүлөрдү жөнөтүү үчүн адегенде операторуңуздан бул кызматты орнотушун сураныңыз. Андан соң, Жөндөөлөрдөн Wi-Fi чалууну кайра күйгүзүңүз."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Операторуңузга катталыңыз"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi чалуу"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-lo-rLA/strings.xml b/core/res/res/values-mcc310-mnc210-lo-rLA/strings.xml
new file mode 100644
index 0000000..d54c935
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-lo-rLA/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"ເພື່ອໂທ ແລະ ສົ່ງຂໍ້ຄວາມຜ່ານ Wi-Fi, ໃຫ້ແຈ້ງຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານເພື່ອຕັ້ງບໍລິການນີ້ກ່ອນ. ຈາກນັ້ນ ເປີດການໂທ Wi-Fi ອີກເທື່ອໜຶ່ງຈາກການຕັ້ງຄ່າ."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ລົງທະບຽນນໍາຜູ້ໃຫ້ບໍລິການເຄືອຂ່າຍຂອງທ່ານ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"ການໂທ %s Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-lt/strings.xml b/core/res/res/values-mcc310-mnc210-lt/strings.xml
new file mode 100644
index 0000000..a8c2a56
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-lt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Jei norite skambinti ir siųsti pranešimus naudodami „Wi-Fi“, pirmiausia paprašykite operatoriaus nustatyti šią paslaugą. Tada vėl įjunkite „Wi-Fi“ skambinimą Nustatymų skiltyje."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Užregistruokite pas operatorių"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"„%s“ „Wi-Fi“ skambinimas"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-lv/strings.xml b/core/res/res/values-mcc310-mnc210-lv/strings.xml
new file mode 100644
index 0000000..566a4f1
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-lv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Lai veiktu zvanus un sūtītu īsziņas Wi-Fi tīklā, vispirms lūdziet mobilo sakaru operatoram iestatīt šo pakalpojumu. Pēc tam iestatījumos vēlreiz ieslēdziet Wi-Fi zvanus."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Reģistrējieties pie sava mobilo sakaru operatora."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi zvani"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-mk-rMK/strings.xml b/core/res/res/values-mcc310-mnc210-mk-rMK/strings.xml
new file mode 100644
index 0000000..f47bbde
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-mk-rMK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"За повикување и испраќање пораки преку Wi-Fi, прво побарајте од операторот да ви ја постави оваа услуга. Потоа повторно вклучете Повици преку Wi-Fi во Поставки."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Регистрирајте се кај операторот"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Повици преку Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ml-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-ml-rIN/strings.xml
new file mode 100644
index 0000000..20bf1eb
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ml-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"വൈഫൈ വഴി കോളുകൾ വിളിക്കാനും സന്ദേശങ്ങൾ അയയ്‌ക്കാനും ആദ്യം നിങ്ങളുടെ കാരിയറോട് ഈ സേവനം സജ്ജമാക്കാൻ ആവശ്യപ്പെടുക. ക്രമീകരണത്തിൽ നിന്ന് വീണ്ടും വൈഫൈ കോളിംഗ് ഓണാക്കുക."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"നിങ്ങളുടെ കാരിയറിൽ രജിസ്റ്റർ ചെയ്യുക"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s വൈഫൈ കോളിംഗ്"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-mn-rMN/strings.xml b/core/res/res/values-mcc310-mnc210-mn-rMN/strings.xml
new file mode 100644
index 0000000..32e7c112
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-mn-rMN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi дуудлага хийх болон зурвас илгээх бол эхлээд оператор компаниасаа энэ төхөөрөмжийг тохируулахыг хүснэ үү. Дараа нь Тохиргооноос Wi-Fi дуудлага хийх үйлдлийг асаана уу."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Оператор компанидаа бүртгүүлэх"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi Дуудлага"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-mr-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-mr-rIN/strings.xml
new file mode 100644
index 0000000..1d29585
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-mr-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"वाय-फायवरून कॉल करण्यासाठी आणि संदेश पाठविण्यासाठी, प्रथम आपल्या वाहकास ही सेवा सेट करण्यास सांगा. नंतर सेटिंग्जमधून पुन्हा वाय-फाय कॉलिंग चालू करा."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"आपल्या वाहकासह नोंदणी करा"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s वाय-फाय कॉलिंग"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ms-rMY/strings.xml b/core/res/res/values-mcc310-mnc210-ms-rMY/strings.xml
new file mode 100644
index 0000000..961f9cf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ms-rMY/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Untuk membuat panggilan dan menghantar mesej melalui Wi-Fi, mula-mula minta pembawa anda menyediakan perkhidmatan ini. Kemudian, hidupkan panggilan Wi-Fi sekali lagi daripada Tetapan."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Daftar dengan pembawa anda"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Panggilan Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-my-rMM/strings.xml b/core/res/res/values-mcc310-mnc210-my-rMM/strings.xml
new file mode 100644
index 0000000..078d196
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-my-rMM/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"ဝိုင်ဖိုင်ကိုအသုံးပြု၍ ဖုန်းခေါ်ဆိုရန်နှင့် စာပို့ရန်၊ ဤစက်ပစ္စည်းကို တပ်ဆင်ရန် သင့်အသုံးပြုသည့်မိုဘိုင်းဝန်ဆောင်မှုအား ဦးစွာမေးပါ။ ထို့နောက် ဆက်တင်များထဲမှ ဝိုင်ဖိုင်ခေါ်ဆိုမှုကို ဖွင့်ပါ။"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"သင့်အသုံးပြုသည့်မိုဘိုင်းဝန်ဆောင်မှုဖြင့် မှတ်ပုံတင်ရန်"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s ဝိုင်ဖိုင်ခေါ်ဆိုမှု"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-nb/strings.xml b/core/res/res/values-mcc310-mnc210-nb/strings.xml
new file mode 100644
index 0000000..36adfa2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Du må be operatøren din om å konfigurere denne tjenesten før du kan ringe og sende meldinger via Wi-Fi. Deretter slår du på Wi-Fi-anrop igjen fra innstillingene."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrer deg hos operatøren din"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi-anrop"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ne-rNP/strings.xml b/core/res/res/values-mcc310-mnc210-ne-rNP/strings.xml
new file mode 100644
index 0000000..9a66faa
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ne-rNP/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi मार्फत कल गर्न र सन्देशहरू पठाउन, सबभन्दा पहिला यो सेवा सेटअप गर्न तपाईँको वाहकलाई भन्नुहोस्। त्यसपछि फेरि सेटिङहरूबाट Wi-Fi कलिङ सक्रिय पार्नुहोस्।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"आफ्नो वाहकसँगै दर्ता गर्नुहोस्"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi कलिङ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-nl/strings.xml b/core/res/res/values-mcc310-mnc210-nl/strings.xml
new file mode 100644
index 0000000..d90df12
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registreren bij je provider"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Bellen via wifi van %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-pa-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-pa-rIN/strings.xml
new file mode 100644
index 0000000..39bdd6405
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-pa-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi \'ਤੇ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਸੁਨੇਹੇ ਭੇਜਣ ਲਈ, ਪਹਿਲਾਂ ਆਪਣੇ ਕੈਰੀਅਰ ਨੂੰ ਇਹ ਸੇਵਾ ਸੈੱਟ ਕਰਨ ਲਈ ਕਹੋ। ਫਿਰ ਸੈਟਿੰਗਾਂ ਤੋਂ Wi-Fi ਕਾਲਿੰਗ ਦੁਬਾਰਾ ਚਾਲੂ ਕਰੋ।"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ਆਪਣੇ ਕੈਰੀਅਰ ਨਾਲ ਰਜਿਸਟਰ ਕਰੋ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi ਕਾਲਿੰਗ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-pl/strings.xml b/core/res/res/values-mcc310-mnc210-pl/strings.xml
new file mode 100644
index 0000000..f6865cf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Zarejestruj u operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Połączenia przez Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-pt-rBR/strings.xml b/core/res/res/values-mcc310-mnc210-pt-rBR/strings.xml
new file mode 100644
index 0000000..90561a2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-pt-rBR/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc210-pt-rPT/strings.xml
new file mode 100644
index 0000000..c5ee6d3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar o serviço. Em seguida, nas Definições, ative novamente as Chamadas Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registar-se junto do seu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Chamadas Wi-Fi da %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-pt/strings.xml b/core/res/res/values-mcc310-mnc210-pt/strings.xml
new file mode 100644
index 0000000..90561a2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ro/strings.xml b/core/res/res/values-mcc310-mnc210-ro/strings.xml
new file mode 100644
index 0000000..90a59c0a
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ro/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Pentru a apela și a trimite mesaje prin Wi-Fi, mai întâi solicitați configurarea acestui serviciu la operator. Apoi, activați din nou apelarea prin Wi-Fi din Setări."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Înregistrați-vă la operatorul dvs."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Apelare prin Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ru/strings.xml b/core/res/res/values-mcc310-mnc210-ru/strings.xml
new file mode 100644
index 0000000..18cd9e0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Укажите оператора и зарегистрируйтесь"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Звонки по Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-si-rLK/strings.xml b/core/res/res/values-mcc310-mnc210-si-rLK/strings.xml
new file mode 100644
index 0000000..bc4e9ee
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-si-rLK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi හරහා ඇමතුම් සිදු කිරීමට සහ පණිවිඩ යැවීමට, පළමුව මෙම සේවාව පිහිටුවන ලෙස ඔබේ වාහකයෙන් ඉල්ලන්න. අනතුරුව සැකසීම් වෙතින් Wi-Fi ඇමතුම නැවත ක්‍රියාත්මක කරන්න."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ඔබගේ වාහකය සමඟ ලියාපදිංචි වන්න"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi අමතමින්"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sk/strings.xml b/core/res/res/values-mcc310-mnc210-sk/strings.xml
new file mode 100644
index 0000000..7fe4d5e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Ak chcete volať a odosielať správy prostredníctvom siete Wi-Fi, kontaktujte najskôr svojho operátora v súvislosti s nastavením tejto služby. Potom opäť zapnite v Nastaveniach volanie cez Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrujte sa so svojím operátorom"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Volanie cez Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sl/strings.xml b/core/res/res/values-mcc310-mnc210-sl/strings.xml
new file mode 100644
index 0000000..f1938a7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Če želite klicati ali pošiljati sporočila prek omrežja Wi-Fi, se najprej obrnite na operaterja, da nastavi to storitev. Nato v nastavitvah znova vklopite klicanje prek omrežja Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registracija pri operaterju"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Klicanje prek omrežja Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sq-rAL/strings.xml b/core/res/res/values-mcc310-mnc210-sq-rAL/strings.xml
new file mode 100644
index 0000000..bcaa4a2
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sq-rAL/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Për të bërë telefonata dhe për të dërguar mesazhe me Wi-Fi, në fillim kërkoji operatorit celular ta konfigurojë këtë shërbim. Më pas aktivizo përsëri telefonatat me Wi-Fi, nga Cilësimet."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Regjistrohu me operatorin tënd celular"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Telefonatat me Wi-Fi nga %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sr/strings.xml b/core/res/res/values-mcc310-mnc210-sr/strings.xml
new file mode 100644
index 0000000..324e5c9
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Да бисте упућивали позиве и слали поруке преко Wi-Fi-ја, прво затражите од мобилног оператера да вам омогући ову услугу. Затим у Подешавањима поново укључите Позивање преко Wi-Fi-ја."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Региструјте се код мобилног оператера"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Wi-Fi позивање преко оператера %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sv/strings.xml b/core/res/res/values-mcc310-mnc210-sv/strings.xml
new file mode 100644
index 0000000..bd329f3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Registrera dig hos operatören"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi-samtal"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-sw/strings.xml b/core/res/res/values-mcc310-mnc210-sw/strings.xml
new file mode 100644
index 0000000..616c3bd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-sw/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Ili upige simu na kutuma ujumbe kupitia Wi-Fi, mwambie mtoa huduma wako asanidi huduma hii kwanza. Kisha uwashe tena upigaji simu kwa Wi-Fi kutoka kwenye Mipangilio."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Jisajili na mtoa huduma wako"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Upigaji Simu kwa Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ta-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-ta-rIN/strings.xml
new file mode 100644
index 0000000..411b8ef
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ta-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"வைஃபை மூலம் அழைக்க மற்றும் செய்திகள் அனுப்ப, முதலில் மொபைல் நிறுவனத்திடம் இந்தச் சேவையை அமைக்குமாறு கேட்கவும். பிறகு அமைப்புகளில் மீண்டும் வைஃபை அழைப்பை இயக்கவும்."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"உங்கள் மொபைல் நிறுவனத்தில் பதிவுசெய்யவும்"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s வைஃபை அழைப்பு"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-te-rIN/strings.xml b/core/res/res/values-mcc310-mnc210-te-rIN/strings.xml
new file mode 100644
index 0000000..d3141d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-te-rIN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fiలో కాల్‌లు చేయడానికి మరియు సందేశాలు పంపడానికి, ముందుగా ఈ సేవను సెటప్ చేయమని మీ క్యారియర్‌ను అడగండి. ఆపై సెట్టింగ్‌ల నుండి Wi-Fi కాలింగ్‌ను మళ్లీ ఆన్ చేయండి."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"మీ క్యారియర్‌తో నమోదు చేయండి"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi కాలింగ్"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-th/strings.xml b/core/res/res/values-mcc310-mnc210-th/strings.xml
new file mode 100644
index 0000000..a7929ee
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-th/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"หากต้องการโทรออกและส่งข้อความผ่าน Wi-Fi โปรดสอบถามผู้ให้บริการของคุณก่อนเพื่อตั้งค่าบริการนี้ แล้วเปิดการโทรผ่าน Wi-Fi อีกครั้งจากการตั้งค่า"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"ลงทะเบียนกับผู้ให้บริการ"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"การโทรผ่าน Wi-Fi ของ %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-tl/strings.xml b/core/res/res/values-mcc310-mnc210-tl/strings.xml
new file mode 100644
index 0000000..2598e22
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-tl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Upang tumawag at magpadala ng mga mensahe sa pamamagitan ng Wi-Fi, hilingin muna sa iyong carrier na i-set up ang serbisyong ito. Pagkatapos ay muling i-on ang pagtawag sa Wi-Fi mula sa Mga Setting."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Magparehistro sa iyong carrier"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Pagtawag Gamit ang Wi-Fi ng %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-tr/strings.xml b/core/res/res/values-mcc310-mnc210-tr/strings.xml
new file mode 100644
index 0000000..1da0b1f
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Operatörünüze kaydolun"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Kablosuz Çağrı"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-uk/strings.xml b/core/res/res/values-mcc310-mnc210-uk/strings.xml
new file mode 100644
index 0000000..37b445d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-uk/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Щоб телефонувати або надсилати повідомлення через Wi-Fi, спершу попросіть свого оператора налаштувати цю послугу. Після цього ввімкніть дзвінки через Wi-Fi у налаштуваннях."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Зареєструйтеся в оператора"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Дзвінок через Wi-Fi від оператора %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-ur-rPK/strings.xml b/core/res/res/values-mcc310-mnc210-ur-rPK/strings.xml
new file mode 100644
index 0000000..150a0bd
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-ur-rPK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"‏Wi-Fi سے کالز کرنے اور پیغامات بھیجنے کیلئے، پہلے اپنے کیریئر سے اس سروس کو سیٹ اپ کرنے کیلئے کہیں۔ پھر ترتیبات سے دوبارہ Wi-Fi کالنگ آن کریں۔"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"اپنے کیریئر کے ساتھ رجسٹر کریں"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"‏‎%s ‏Wi-Fi کالنگ"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-uz-rUZ/strings.xml b/core/res/res/values-mcc310-mnc210-uz-rUZ/strings.xml
new file mode 100644
index 0000000..6e9b7e0
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-uz-rUZ/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Wi-Fi orqali qo‘ng‘iroqlarni amalga oshirish va xabarlar bilan almashinish uchun uyali aloqa operatoringizdan ushbu xizmatni yoqib qo‘yishni so‘rashingiz lozim. Keyin sozlamalarda Wi-Fi qo‘ng‘irog‘i imkoniyatini yoqib olishingiz mumkin."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Mobil operatoringiz yordamida ro‘yxatdan o‘ting"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi qo‘ng‘iroqlar"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-vi/strings.xml b/core/res/res/values-mcc310-mnc210-vi/strings.xml
new file mode 100644
index 0000000..302c51d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-vi/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Để gọi điện và gửi tin nhắn qua Wi-Fi, trước tiên hãy yêu cầu nhà cung cấp dịch vụ của bạn thiết lập dịch vụ này. Sau đó, bật lại gọi qua Wi-Fi từ Cài đặt."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Đăng ký với nhà cung cấp dịch vụ của bạn"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"Gọi điện qua Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc210-zh-rCN/strings.xml
new file mode 100644
index 0000000..3562239
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"向您的运营商注册"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s WLAN 通话功能"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-zh-rHK/strings.xml b/core/res/res/values-mcc310-mnc210-zh-rHK/strings.xml
new file mode 100644
index 0000000..f890edf
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-zh-rHK/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"如要透過 Wi-Fi 撥打電話和傳送訊息,請先向流動網絡供應商要求設定此服務,然後再次在「設定」中開啟 [Wi-Fi 通話]。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"向您的流動網絡供應商註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc210-zh-rTW/strings.xml
new file mode 100644
index 0000000..13ef816
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"向您的行動通訊業者註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc210-zu/strings.xml b/core/res/res/values-mcc310-mnc210-zu/strings.xml
new file mode 100644
index 0000000..cde0a8c
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc210-zu/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="5217754856196352581">"Ukuze wenze amakholi uphinde uthumele imilayezo nge-Wi-Fi, qala ucele inkampani yakho yenethiwekhi ukuthi isethe le divayisi. Bese uvula ukushaya kwe-Wi-Fi futhi kusukela kuzilungiselelo."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="4688475512286389971">"Bhalisa ngenkampani yakho yenethiwekhi"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="5475635312889002673">"%s ukushaya kwe-Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-ar/strings.xml b/core/res/res/values-mcc310-mnc220-ar/strings.xml
new file mode 100644
index 0000000..229c9ce
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-ar/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"‏لإجراء مكالمات وإرسال رسائل عبر Wi-Fi، اطلب من مشغّل شبكة الجوّال أولاً إعداد هذه الخدمة، ثم شغّل الاتصال عبر Wi-Fi مرة أخرى من خلال الإعدادات."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"التسجيل لدى مشغّل شبكة الجوّال"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"‏%s جارٍ الاتصال عبر Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-cs/strings.xml b/core/res/res/values-mcc310-mnc220-cs/strings.xml
new file mode 100644
index 0000000..776c183
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-cs/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Chcete-li volat a odesílat textové zprávy přes síť Wi-Fi, nejprve požádejte operátora, aby vám tuto službu nastavil. Poté volání přes Wi-Fi opět zapněte v Nastavení."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registrace u operátora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Volání přes Wi-Fi: %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-da/strings.xml b/core/res/res/values-mcc310-mnc220-da/strings.xml
new file mode 100644
index 0000000..de6b124
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-da/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Før du kan foretage opkald og sende beskeder via Wi-Fi, skal du anmode dit mobilselskab om at konfigurere denne tjeneste. Du skal derefter slå Wi-Fi-opkald til igen fra Indstillinger."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registrer dig hos dit mobilselskab"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Wi-Fi-opkald"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-de/strings.xml b/core/res/res/values-mcc310-mnc220-de/strings.xml
new file mode 100644
index 0000000..b7cdd38
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-de/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Um über WLAN telefonieren und Nachrichten senden zu können, bitte zuerst deinen Mobilfunkanbieter, diesen Dienst einzurichten. Aktiviere die Option \"Anrufe über WLAN\" dann noch einmal über die Einstellungen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registriere dich bei deinem Mobilfunkanbieter"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s-WLAN-Anrufe"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-el/strings.xml b/core/res/res/values-mcc310-mnc220-el/strings.xml
new file mode 100644
index 0000000..940e23d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-el/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Για να κάνετε κλήσεις και να στέλνετε μηνύματα μέσω Wi-Fi, ζητήστε πρώτα από την εταιρεία κινητής τηλεφωνίας να ρυθμίσει την υπηρεσία. Στη συνέχεια, ενεργοποιήστε ξανά τη λειτουργία Κλήσης Wi-Fi από τις Ρυθμίσεις."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Εγγραφείτε μέσω της εταιρείας κινητής τηλεφωνίας"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Κλήση Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-es-rUS/strings.xml b/core/res/res/values-mcc310-mnc220-es-rUS/strings.xml
new file mode 100644
index 0000000..6df96d8
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-es-rUS/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Para realizar llamadas y enviar mensajes con Wi-Fi, primero solicítale al proveedor que instale el servicio. Luego, vuelve a activar Llamada con Wi-Fi en Configuración."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Regístrate con tu proveedor"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Llamada con Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-es/strings.xml b/core/res/res/values-mcc310-mnc220-es/strings.xml
new file mode 100644
index 0000000..5292afe
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-es/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Para hacer llamadas y enviar mensajes por Wi-Fi, solicita a tu operador que configure este servicio y, cuando lo haga, vuelve a activar las llamadas por Wi-Fi en Ajustes."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Regístrate con tu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Llamada por Wi-Fi de %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-fr/strings.xml b/core/res/res/values-mcc310-mnc220-fr/strings.xml
new file mode 100644
index 0000000..dec321e
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-fr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Pour passer des appels et envoyer des messages via le Wi-Fi, demandez d\'abord à votre opérateur de configurer ce service. Ensuite, réactivez les appels Wi-Fi dans les paramètres."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Inscrivez-vous auprès de votre opérateur."</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Appels Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-it/strings.xml b/core/res/res/values-mcc310-mnc220-it/strings.xml
new file mode 100644
index 0000000..04bfca3
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-it/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Per poter effettuare chiamate e inviare messaggi tramite Wi-Fi, devi chiedere all\'operatore di attivare il servizio. Dopodiché, riattiva le chiamate Wi-Fi dalle Impostazioni."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registrati con il tuo operatore"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Chiamate Wi-Fi %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-ja/strings.xml b/core/res/res/values-mcc310-mnc220-ja/strings.xml
new file mode 100644
index 0000000..71956ec
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-ja/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Wi-Fi 経由で音声通話の発信やメッセージの送信を行うには、携帯通信会社に Wi-Fi サービスを申し込んだ上で、設定画面で Wi-Fi 発信を再度 ON にしてください。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"携帯通信会社に登録してください"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Wi-Fi 通話(%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-ko/strings.xml b/core/res/res/values-mcc310-mnc220-ko/strings.xml
new file mode 100644
index 0000000..40d0865
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-ko/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Wi-Fi를 사용하여 전화를 걸고 메시지를 보내려면 먼저 이동통신사에 문의하여 이 기능을 설정해야 합니다. 그런 다음 설정에서 Wi-Fi 통화를 사용 설정하시기 바랍니다."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"이동통신사에 등록"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Wi-Fi 통화"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-nb/strings.xml b/core/res/res/values-mcc310-mnc220-nb/strings.xml
new file mode 100644
index 0000000..798bb7d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-nb/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Du må be operatøren din om å konfigurere denne tjenesten før du kan ringe og sende meldinger via Wi-Fi. Deretter slår du på Wi-Fi-anrop igjen fra innstillingene."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registrer deg hos operatøren din"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Wi-Fi-anrop"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-nl/strings.xml b/core/res/res/values-mcc310-mnc220-nl/strings.xml
new file mode 100644
index 0000000..ed37e20
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-nl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Als je wilt bellen en berichten wilt verzenden via wifi, moet je eerst je provider vragen deze service in te stellen. Schakel bellen via wifi vervolgens opnieuw in via Instellingen."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registreren bij je provider"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Bellen via wifi van %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-pl/strings.xml b/core/res/res/values-mcc310-mnc220-pl/strings.xml
new file mode 100644
index 0000000..077c426
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-pl/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Aby dzwonić i wysyłać wiadomości przez Wi-Fi, poproś swojego operatora o skonfigurowanie tej usługi. Potem ponownie włącz połączenia przez Wi-Fi w Ustawieniach."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Zarejestruj u operatora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Połączenia przez Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-pt-rPT/strings.xml b/core/res/res/values-mcc310-mnc220-pt-rPT/strings.xml
new file mode 100644
index 0000000..20799a7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-pt-rPT/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Para fazer chamadas e enviar mensagens por Wi-Fi, comece por pedir ao seu operador para configurar o serviço. Em seguida, nas Definições, ative novamente as Chamadas Wi-Fi."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registar-se junto do seu operador"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Chamadas Wi-Fi da %s"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-pt/strings.xml b/core/res/res/values-mcc310-mnc220-pt/strings.xml
new file mode 100644
index 0000000..3a32281
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-pt/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Para fazer chamadas e enviar mensagens por Wi-Fi, primeiro peça à sua operadora para configurar esse serviço. Depois, ative novamente as chamadas por Wi-Fi nas configurações."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Faça registro na sua operadora"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s chamada Wi-Fi"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-ru/strings.xml b/core/res/res/values-mcc310-mnc220-ru/strings.xml
new file mode 100644
index 0000000..46a8d6f
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-ru/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Чтобы совершать звонки и отправлять сообщения по Wi-Fi, необходимо сначала обратиться к оператору связи и подключить эту услугу. После этого вы сможете снова выбрать этот параметр в настройках."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Укажите оператора и зарегистрируйтесь"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"Звонки по Wi-Fi (%s)"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-sv/strings.xml b/core/res/res/values-mcc310-mnc220-sv/strings.xml
new file mode 100644
index 0000000..056824d
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-sv/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Om du vill ringa samtal och skicka meddelanden via Wi-Fi ber du först operatören att konfigurera tjänsten. Därefter kan du aktivera Wi-Fi-samtal på nytt från Inställningar."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Registrera dig hos operatören"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Wi-Fi-samtal"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-tr/strings.xml b/core/res/res/values-mcc310-mnc220-tr/strings.xml
new file mode 100644
index 0000000..47aa7b7
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-tr/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"Kablosuz ağ üzerinden telefon etmek ve ileti göndermek için ilk önce operatörünüzden bu hizmeti ayarlamasını isteyin. Sonra, Ayarlar\'dan Kablosuz çağrı özelliğini tekrar açın."</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"Operatörünüze kaydolun"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Kablosuz Çağrı"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-zh-rCN/strings.xml b/core/res/res/values-mcc310-mnc220-zh-rCN/strings.xml
new file mode 100644
index 0000000..a64a3b5
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-zh-rCN/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"要通过 WLAN 打电话和发信息,请先让您的运营商开通此服务,然后再到“设置”中重新开启 WLAN 通话功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"向您的运营商注册"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s WLAN 通话功能"</string>
+</resources>
diff --git a/core/res/res/values-mcc310-mnc220-zh-rTW/strings.xml b/core/res/res/values-mcc310-mnc220-zh-rTW/strings.xml
new file mode 100644
index 0000000..1673efc
--- /dev/null
+++ b/core/res/res/values-mcc310-mnc220-zh-rTW/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You my obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--  These resources are around just to allow their values to be customized
+     for different hardware and product builds.  -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="wfcOperatorErrorAlertMessages">
+    <item msgid="6238990105876016549">"如要透過 Wi-Fi 撥打電話及傳送訊息,請先要求您的行動通訊業者開通這項服務,然後再到「設定」啟用 Wi-Fi 通話功能。"</item>
+  </string-array>
+  <string-array name="wfcOperatorErrorNotificationMessages">
+    <item msgid="2866631708941520085">"向您的行動通訊業者註冊"</item>
+  </string-array>
+    <string name="wfcSpnFormat" msgid="3422704506272221128">"%s Wi-Fi 通話"</string>
+</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index d67d78d..d4f1722 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Допри за повеќе опции."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Да се сподели извештајот за грешки со администраторот?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Вашиот ИТ-администратор побара извештај за грешки за да помогне со отстранување на грешките"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИФАТИ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОДБИЈ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Се зема извештајот за грешки…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Допрете за да откажете"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Измени тастатура"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Избери тастатури"</string>
     <string name="show_ime" msgid="2506087537466597099">"Прикажувај го на екранот додека е активна физичката тастатура"</string>
@@ -1557,9 +1563,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Оневозможено од администраторот на %1$s. Контактирајте со него за да дознаете повеќе."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Имате нови пораки"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Отворете ја апликацијата за СМС за приказ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Некои функции се недостапни"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Допрете за да продолжите"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Корисничкиот профил е заклучен"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Некои функции се ограничени"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Допрете за да отклучите"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Кориснички податоци, заклучени"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Работниот профил е заклучен"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Допрете за да го отклучите"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Поврзан на <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Допрете за да ги погледнете датотеките"</string>
     <string name="pin_target" msgid="3052256031352291362">"Прикачете"</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 43c232f..f4c7243 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"കൂടുതൽ ഓപ്‌ഷനുകൾക്ക് സ്‌പർശിക്കൂ."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്‌റ്റുചെയ്‌തു"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ സ്‌പർശിക്കൂ."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"അഡ്‌മിനുമായി ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"പ്രശ്നം പരിഹരിക്കുന്നതിന് നിങ്ങളുടെ ഐടി അഡ്‌മിൻ ഒരു ബഗ് റിപ്പോർട്ട് അഭ്യർത്ഥിച്ചു"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"അംഗീകരിക്കുക"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"നിരസിക്കുക"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"റദ്ദാക്കുന്നതിന് സ്പർശിക്കുക"</string>
     <string name="select_input_method" msgid="8547250819326693584">"കീബോഡ് മാറ്റുക"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"കീബോർഡുകൾ തിരഞ്ഞെടുക്കുക"</string>
     <string name="show_ime" msgid="2506087537466597099">"ഫിസിക്കൽ കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string>
@@ -1220,7 +1226,7 @@
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"ഡോട്ട്."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"ഹോമിലേക്ക് നാവിഗേറ്റുചെയ്യുക"</string>
     <string name="action_bar_up_description" msgid="2237496562952152589">"മുകളിലേക്ക് നാവിഗേറ്റുചെയ്യുക"</string>
-    <string name="action_menu_overflow_description" msgid="2295659037509008453">"കൂടുതല്‍ ഓപ്‌ഷനുകള്‍"</string>
+    <string name="action_menu_overflow_description" msgid="2295659037509008453">"കൂടുതൽ‍ ഓപ്‌ഷനുകള്‍"</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">"ആന്തരിക സ്റ്റോറേജ്"</string>
@@ -1529,7 +1535,7 @@
     <string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB പെരിഫറൽ പോർട്ട്"</string>
     <string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
     <string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB പെരിഫറൽ പോർട്ട്"</string>
-    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"കൂടുതല്‍ ഓപ്ഷനുകള്‍"</string>
+    <string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"കൂടുതൽ‍ ഓപ്ഷനുകള്‍"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"ഓവർഫ്ലോ അടയ്‌ക്കുക"</string>
     <string name="maximize_button_text" msgid="7543285286182446254">"വലുതാക്കുക"</string>
     <string name="close_button_text" msgid="3937902162644062866">"അടയ്‌ക്കുക"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s അഡ്മിനിസ്ട്രേറ്റർ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു. കൂടുതലറിയാൻ അഡ്മിനിസ്ട്രേറ്ററെ ബന്ധപ്പെടുക."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"നിങ്ങൾക്ക് പുതിയ സന്ദേശങ്ങൾ ഉണ്ട്"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"കാണുന്നതിന് SMS ആപ്പ് തുറക്കുക"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ചില ഫംഗ്ഷനുകൾ ലഭ്യമായേക്കില്ല"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"തുടരുന്നതിന് സ്പർശിക്കുക"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ഉപയോക്തൃ പ്രൊഫൈൽ ലോക്കുചെയ്തു"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ചില പ്രവർത്തനക്ഷമതകൾ പരിമിതപ്പെടാം"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"അൺലോക്കുചെയ്യാൻ ടാപ്പുചെയ്യുക"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ഉപയോക്തൃ ഡാറ്റ ലോക്കുചെയ്തു"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ഔദ്യോഗിക പ്രൊഫൈൽ ലോക്കുചെയ്തു"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ഔദ്യോഗിക പ്രൊഫൈൽ അൺലോക്കുചെയ്യാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> എന്നതിലേക്ക് കണക്റ്റുചെയ്തു"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ഫയലുകൾ കാണുന്നതിന് ടാപ്പുചെയ്യുക"</string>
     <string name="pin_target" msgid="3052256031352291362">"പിൻ ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index dacb292..aba5bc0 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Нэмэлт сонголтыг харахын тулд дарна."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебагийг идэвхгүй болгох бол хүрнэ үү."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Алдааны тайланг админтай хуваалцах уу?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Асуудлыг шийдвэрлэхийн таны МТ админтулд алдааны тайланг хүслээ"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ЗӨВШӨӨРӨХ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ТАТГАЛЗАХ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Алдааны тайланг авч байна..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Цуцлахын тулд хүрэх"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Гар сонгох"</string>
     <string name="show_ime" msgid="2506087537466597099">"Бодит гар идэвхтэй үед үүнийг дэлгэцэнд харуулна уу"</string>
@@ -1553,9 +1559,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s админ идэвхгүй болгосон. Дэлгэрэнгүй мэдэхийн тулд тэдэнтэй холбоо барина уу."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Танд шинэ зурвасууд байна"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Үзэхийн тулд SMS аппыг нээх"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Зарим функц байхгүй"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Үргэлжлүүлэхийн тулд дарах"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Хэрэглэгчийн профайл түгжээтэй"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Зарим үйлдэл хязгаарлалттай байж болно"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Түгжээг тайлахын тулд дар"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Хэрэглэгчийн мэдээлэл түгжигдсэн"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Ажлын профайлыг түгжсэн"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ажлын профайлын түгжээг тайлахын тулд дарна уу"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>-д холбогдсон"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Файлыг үзэхийн тулд дарна уу"</string>
     <string name="pin_target" msgid="3052256031352291362">"PIN"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 3041601..1b1c7a8 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"अधिक पर्यायांसाठी स्पर्श करा."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्‍ट केले"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करणे अक्षम करण्यासाठी स्पर्श करा."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"प्रशासकासह दोष अहवाल सामायिक करायचा?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"आपल्या IT प्रशासकाने समस्या निवारण करण्‍यात मदत करण्यासाठी दोष अहवालाची विनंती केली"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार करा"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"नकार द्या"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"दोष अहवाल घेत आहे..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द करण्यासाठी स्पर्श करा"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदला"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड निवडा"</string>
     <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s प्रशासकाद्वारे अक्षम केले. अधिक जाणून घेण्‍यासाठी त्यांच्याशी संपर्क साधा."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"आपल्याकडे नवीन संदेश आहेत"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"पाहण्‍यासाठी SMS अॅप उघडा"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"काही कार्ये कदाचित उपलब्ध नसू शकतात"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"सुरू ठेवण्यासाठी स्पर्श करा"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"वापरकर्ता प्रोफाईल लॉक केले"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"काही कार्यक्षमता मर्यादित असू शकतात"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"अनलॉक करण्यासाठी टॅप करा"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"वापरकर्ता डेटा लॉक केला"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"कार्य प्रोफाईल लॉक केले"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाईल अनलॉक करण्यासाठी टॅप करा"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> शी कनेक्ट केलेले"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फायली पाहण्यासाठी टॅप करा"</string>
     <string name="pin_target" msgid="3052256031352291362">"पिन"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 0f5156a..f174b7c 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sentuh untuk mendapatkan lagi pilihan."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Kongsi laporan pepijat dengan pentadbir?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Pentadbir IT anda meminta laporan pepijat untuk membantu menyelesaikan masalah"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"TERIMA"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TOLAK"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Mengambil laporan pepijat…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Sentuh untuk membatalkan"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Tukar papan kekunci"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pilih papan kekunci"</string>
     <string name="show_ime" msgid="2506087537466597099">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Dilumpuhkan oleh pentadbir %1$s. Hubungi mereka untuk mengetahui lebih lanjut."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Anda mempunyai mesej baharu"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Buka apl SMS untuk melihat"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Sesetengah fungsi mgkn tidak tersedia"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Ketik untuk meneruskan"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil pengguna dikunci"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Beberapa fungsi mungkin terhad"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Ketik untuk membuka kunci"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Data pengguna dikunci"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil kerja dikunci"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ketik utk membuka profil kerja"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Disambungkan ke <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Ketik untuk melihat fail"</string>
     <string name="pin_target" msgid="3052256031352291362">"Semat"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index ca28662..6fe0c88 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ထပ်မံရွေးချယ်စရာများအတွက် ထိပါ"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ဒီဘာဂင် ပိတ်ရန် ထိပါ။"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို စီမံအုပ်ချုပ်သူထံ ပို့မလား။"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"သင်၏ IT စီမံအုပ်ချုပ်သူက ပြဿနာကို ဖြေရှင်းနိုင်ရန် ချွတ်ယွင်းချက်အစီရင်ခံစာကို တောင်းဆိုပါသည်"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"လက်ခံပါ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ငြင်းပယ်ပါ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ချွတ်ယွင်းချက် စာရင်းကို ယူနေပါသည်..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ဖျက်သိမ်းရန် တို့ပါ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ကီးဘုတ်များကို ရွေးရန်"</string>
     <string name="show_ime" msgid="2506087537466597099">"စက်၏ကီးဘုတ်ကိုအသုံးပြုနေစဉ် ၎င်းကိုမျက်နှာပြင်ပေါ်တွင် ထားပါ"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s စီမံခန့်ခွဲသူမှ ပိတ်ထားသည်။ ပိုမိုလေ့လာရန် ၎င်းတို့ကိုဆက်သွယ်ပါ။"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"သင့်ထံတွင် စာအသစ်များရောက်နေသည်"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"ကြည့်ရှုရန် SMS အက်ပ်ကိုဖွင့်ပါ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"အချို့လုပ်ဆောင်ချက်များ ရနိုင်သေးမည်မဟုတ်ပါ"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ရှေ့ဆက်ရန်တို့ပါ"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"အသုံးပြုသူပရိုဖိုင် သော့ခတ်ထားသည်"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"အချို့လုပ်ဆောင်ချက်များ ကန့်သတ်ချက်ရှိနိုင်သည်"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"သော့ဖွင့်ရန် တို့ပါ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"အသုံးပြုသူဒေတာအား သော့ခတ်ထားသည်"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"အလုပ်ပရိုဖိုင် သော့ခတ်ထားသည်"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"သင့်အလုပ်ပရိုဖိုင်ကို သော့ဖွင့်ရန် တို့ပါ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ချိတ်ဆက်ထားသည်"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ဖိုင်များကိုကြည့်ရန် တို့ပါ"</string>
     <string name="pin_target" msgid="3052256031352291362">"တွဲပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 737743a..3c7bfe3 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Trykk for å se flere alternativer."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å slå av USB-feilsøking."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vil du dele feilrapporten med administratoren?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administratoren din har bedt om en feilrapport for å hjelpe med feilsøkingen"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"GODTA"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AVSLÅ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Kjører feilrapport …"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Trykk for å avbryte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Velg tastatur"</string>
     <string name="show_ime" msgid="2506087537466597099">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string>
@@ -1557,9 +1563,11 @@
     <skip />
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du har nye meldinger"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Åpne SMS-appen for å se"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Noen funksjoner kan være utilgjengelige"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Trykk for å fortsette"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Brukerprofilen er låst"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Enkelte funksjoner kan være begrenset"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Trykk for å låse opp"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Brukerdataene er låst"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Jobbprofilen er låst"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Trykk for å låse opp jobbprofilen"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Koblet til <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Trykk for å se filer"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fest"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 7ea4b48..3379af7 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1059,12 +1059,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"थप विकल्पहरूका लागि छुनुहोस्।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डिबग गर्ने जडित छ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डिबग गर्ने असक्षम पार्न छुनुहोस्।"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"प्रशासकसँग बग रिपोर्ट साझेदारी गर्ने हो?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"तपाईंको IT व्यवस्थापकले समस्या निवारणमा मद्दत गर्न बग रिपोर्ट अनुरोध गर्नुभयो"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"स्वीकार गर्नुहोस्"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"अस्वीकार गर्नुहोस्"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"बग रिपोर्ट लिँदै..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"रद्द गर्न छुनुहोस्"</string>
     <string name="select_input_method" msgid="8547250819326693584">"कुञ्जीपाटी परिवर्तन गर्नुहोस्"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड छान्नुहोस्"</string>
     <string name="show_ime" msgid="2506087537466597099">"भौतिक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string>
@@ -1561,9 +1567,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s प्रशासकद्वारा असक्षम गरिएको। थप जान्नका लागि तिनीहरूलाई सम्पर्क गर्नुहोस्।"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"तपाईंलाई नयाँ सन्देश आएको छ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"हेर्नका लागि SMS अनुप्रयोग खोल्नुहोस्"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"केही कार्यहरू उपलब्ध नहुन सक्छन्"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"जारी राख्नका लागि छुनुहोस्"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"प्रयोगकर्ता प्रोफाइल लक भयो"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"केही कार्य सीमित हुनसक्छ"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"अनलक गर्न ट्याप गर्नुहोस्"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"प्रयोगकर्ताको डेटा लक गरियो"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"कार्य प्रोफाइल बन्द भयो"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"कार्य प्रोफाइल अनलक गर्न ट्याप गर्नुहोस्"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> मा जडान गरिएको छ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"फाइलहरू हेर्न ट्याप गर्नुहोस्"</string>
     <string name="pin_target" msgid="3052256031352291362">"पिन गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 750b716..ad987a2 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Tik voor meer opties."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tik om USB-foutopsporing uit te schakelen."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Bugrapport delen met beheerder?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Je IT-beheerder heeft een bugrapport aangevraagd om het probleem op te lossen"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTEREN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"WEIGEREN"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Bugrapport genereren…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tik om te annuleren"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Toetsenbord wijzigen"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Toetsenborden kiezen"</string>
     <string name="show_ime" msgid="2506087537466597099">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Uitgeschakeld door de beheerder van %1$s. Neem voor meer informatie contact op met de beheerder."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Je hebt nieuwe berichten"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Open je sms-app om ze te bekijken"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Sommige functies zijn mogelijk niet beschikbaar"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Tik om door te gaan"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Gebruikersprofiel vergrendeld"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Bepaalde functionaliteit kan zijn beperkt"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tik om te ontgrendelen"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Gebruikersgegevens vergrendeld"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Werkprofiel vergrendeld"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Ontgrendel werkprofiel met tik"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Verbonden met <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tik om bestanden te bekijken"</string>
     <string name="pin_target" msgid="3052256031352291362">"Vastzetten"</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 05f0ce2..be6ddde 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਸਪਰਸ਼ ਕਰੋ।"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ਡੀਬਗਿੰਗ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਛੋਹਵੋ।"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ਕੀ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ਸਮੱਸਿਆ ਦੇ ਨਿਪਟਾਰੇ ਵਿੱਚ ਮਦਦ ਲਈ ਤੁਹਾਡੇ IT ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਇੱਕ ਬੱਗ ਰਿਪੋਰਟ ਦੀ ਬੇਨਤੀ ਕੀਤੀ"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ਰੱਦ ਕਰਨ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
     <string name="select_input_method" msgid="8547250819326693584">"ਕੀਬੋਰਡ ਬਦਲੋ"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"ਕੀਬੋਰਡਸ ਚੁਣੋ"</string>
     <string name="show_ime" msgid="2506087537466597099">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਹੋਰ ਜਾਣਨ ਲਈ ਉਹਨਾਂ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"ਤੁਹਾਨੂੰ ਨਵੇਂ ਸੁਨੇਹੇ ਪ੍ਰਾਪਤ ਹੋਏ ਹਨ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"ਵੇਖਣ ਲਈ SMS ਐਪ ਖੋਲ੍ਹੋ"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ਹੋ ਸਕਦਾ ਹੈ ਕੁਝ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਉਪਲਬਧ ਨਾ ਹੋਣ"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"ਵਰਤੋਂਕਾਰ ਪ੍ਰੋਫਾਈਲ ਲੌਕ ਕੀਤੀ ਗਈ"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ਕੁਝ ਪ੍ਰਕਾਰਜਾਤਮਕਤਾ ਸੀਮਿਤ ਹੋ ਸਕਦੀ ਹੈ"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ਵਰਤੋਂਕਾਰ ਡੈਟਾ ਲੌਕ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਲੌਕ ਕੀਤੀ ਗਈ"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਨੂੰ ਅਨਲੌਕ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋਈ"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ਫ਼ਾਈਲਾਂ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="pin_target" msgid="3052256031352291362">"ਪਿੰਨ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7e320a6..4700873 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Kliknij, by zobaczyć więcej opcji."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknij, aby wyłączyć debugowanie USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Udostępnić raport o błędzie administratorowi?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administrator poprosił o raport o błędzie, który pomoże w rozwiązaniu problemu"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"AKCEPTUJ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODRZUĆ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Zgłaszam błąd…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Kliknij, by anulować"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmień klawiaturę"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Wybierz klawiatury"</string>
     <string name="show_ime" msgid="2506087537466597099">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Wyłączone przez administratora organizacji %1$s. Skontaktuj się z nim, by dowiedzieć się więcej."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Masz nowe wiadomości"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otwórz aplikację do SMS-ów, by wyświetlić wiadomość"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Niektóre funkcje mogą być niedostępne"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Kliknij, by kontynuować"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil użytkownika zablokowany"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Niektóre funkcje mogą być niedostępne"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Kliknij, by odblokować"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dane użytkownika zablokowane"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil do pracy zablokowany"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Kliknij, by odblokować profil"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Połączono z: <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dotknij, by wyświetlić pliki"</string>
     <string name="pin_target" msgid="3052256031352291362">"Przypnij"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1e3a887..478165c 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Compartilhar o relatório do bug com o administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Seu administrador de TI solicitou um relatório do bug para ajudar a resolver problemas"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Gerando relatório do bug..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Desativado pelo administrador de %1$s. Entre em contato com ele para saber mais."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Você tem mensagens novas"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abra o app de SMS para ver"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Algumas funções podem não estar disponíveis."</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toque para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil do usuário bloqueado"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Algumas funcionalidades são limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toque para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dados do usuário bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de trabalho bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque para desbloquear perfil de trabalho"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toque para ver os arquivos"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixar guia"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 69520ee..038bfe9 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desat. a depuração USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Pretende partilhar o relatório de erros com o administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"O seu administrador de TI solicitou um relatório de erros para ajudar na resolução de problemas"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"A criar relatório de erros…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Manter no ecrã enquanto o teclado físico estiver ativo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Desativado pelo administrador de %1$s. Contacte-o para saber mais."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Tem mensagens novas"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abra a aplicação de SMS para ver"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Algumas funções podem não estar disp."</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toque para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil de utilizador bloqueado"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Algumas funcionalid. limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toque para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dados do utilizador bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de trabalho bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque p/ desb. perfil trabalho"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ligado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Tocar para ver ficheiros"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixar"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1e3a887..478165c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Compartilhar o relatório do bug com o administrador?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Seu administrador de TI solicitou um relatório do bug para ajudar a resolver problemas"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACEITAR"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RECUSAR"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Gerando relatório do bug..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Toque para cancelar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string>
     <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Desativado pelo administrador de %1$s. Entre em contato com ele para saber mais."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Você tem mensagens novas"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Abra o app de SMS para ver"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Algumas funções podem não estar disponíveis."</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Toque para continuar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Perfil do usuário bloqueado"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Algumas funcionalidades são limitadas"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Toque para desbloquear"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Dados do usuário bloqueados"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Perfil de trabalho bloqueado"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Toque para desbloquear perfil de trabalho"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectado a <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Toque para ver os arquivos"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixar guia"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 9783507..f707822 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -82,7 +82,7 @@
     <string name="ThreeWCMmi" msgid="9051047170321190368">"Apelare de tip conferință"</string>
     <string name="RuacMmi" msgid="7827887459138308886">"Respingere apeluri supărătoare nedorite"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Se apelează serviciul de furnizare a numerelor"</string>
-    <string name="DndMmi" msgid="1265478932418334331">"Nu deranjaţi"</string>
+    <string name="DndMmi" msgid="1265478932418334331">"Nu deranjați"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"ID-ul apelantului este restricţionat în mod prestabilit. Apelul următor: restricţionat"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"ID-ul apelantului este restricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: Restricționat."</string>
@@ -120,7 +120,7 @@
     <string name="roamingText7" msgid="7112078724097233605">"Roaming - partenerAlliance"</string>
     <string name="roamingText8" msgid="5989569778604089291">"Roaming - partener Premium"</string>
     <string name="roamingText9" msgid="7969296811355152491">"Roaming - funcţionalitate completă a serviciului"</string>
-    <string name="roamingText10" msgid="3992906999815316417">"Roaming - funcţionalitate parţială a serviciului"</string>
+    <string name="roamingText10" msgid="3992906999815316417">"Roaming - funcţionalitate parțială a serviciului"</string>
     <string name="roamingText11" msgid="4154476854426920970">"Banner roaming activat"</string>
     <string name="roamingText12" msgid="1189071119992726320">"Banner roaming dezactivat"</string>
     <string name="roamingTextSearching" msgid="8360141885972279963">"Se caută serviciul"</string>
@@ -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>
@@ -279,22 +279,22 @@
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Permite unei aplicații să adauge comenzi rapide pe ecranul de pornire, fără intervenția utilizatorului."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"dezinstalează comenzi rapide"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite aplicației să elimine comenzi rapide de pe ecranul de pornire, fără intervenția utilizatorului."</string>
-    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecţionează apelurile efectuate"</string>
+    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecționează apelurile efectuate"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite aplicației să vadă numărul format în timpul unui apel de ieșire, cu opțiunea de a redirecționa apelul către un alt număr sau de a întrerupe apelul."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"primeşte mesaje text (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicației să primească și să proceseze mesaje SMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"primeşte mesaje text (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Permite aplicației să primească și să proceseze mesaje MMS. Acest lucru înseamnă că aplicația ar putea monitoriza sau șterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"citește mesajele cu transmisie celulară"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locații pentru a vă avertiza cu privire la situațiile de urgenţă. Aplicaţiile rău intenţionate pot afecta performanța sau funcționarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Permite aplicației să citească mesajele primite prin transmisie celulară de dispozitivul dvs. Alertele cu transmisie celulară sunt difuzate în unele locații pentru a vă avertiza cu privire la situațiile de urgenţă. Aplicațiile rău intenţionate pot afecta performanța sau funcționarea dispozitivului dvs. când este primită o transmisie celulară de urgenţă."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"citire feeduri abonat"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Permite aplicației să obţină detalii despre feedurile sincronizate în prezent."</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"trimită și să vadă mesajele SMS"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"Permite aplicației să trimită mesaje SMS, ceea ce ar putea determina apariția unor taxe neașteptate. Aplicaţiile rău intenţionate pot acumula costuri prin trimiterea mesajelor fără confirmarea dvs."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Permite aplicației să trimită mesaje SMS, ceea ce ar putea determina apariția unor taxe neașteptate. Aplicațiile rău intenţionate pot acumula costuri prin trimiterea mesajelor fără confirmarea dvs."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"citește mesajele text (SMS sau MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite aplicației să citească mesajele SMS stocate pe tabletă sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidenţialitate al acestora."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Permite aplicației să citească mesajele SMS stocate pe tabletă sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidențialitate al acestora."</string>
     <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Permite aplicației să citească mesajele SMS stocate pe televizor sau pe cardul SIM. Cu această permisiune, aplicația poate citi toate mesajele SMS, indiferent de conținutul sau de gradul de confidențialitate al acestora."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permite aplicației să citească mesajele SMS stocate pe telefon sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidenţialitate al acestora."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Permite aplicației să citească mesajele SMS stocate pe telefon sau pe cardul SIM. În acest fel, aplicația poate citi toate mesajele SMS, indiferent de conţinutul sau de gradul de confidențialitate al acestora."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"primeşte mesaje text (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Permite aplicației să primească și să proceseze mesaje WAP. Această permisiune include capacitatea de a monitoriza sau șterge mesajele care v-au fost trimise fără a vi le arăta."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"preluare aplicații care rulează"</string>
@@ -302,13 +302,13 @@
     <string name="permlab_manageProfileAndDeviceOwners" msgid="7918181259098220004">"să gestioneze profilul și proprietarii dispozitivului"</string>
     <string name="permdesc_manageProfileAndDeviceOwners" msgid="106894851498657169">"Permite aplicațiilor să seteze proprietarii de profiluri și proprietarul dispozitivului."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"reordonare aplicații care rulează"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite aplicației să mute activităţile în prim-plan și în fundal. Aplicaţia poate face acest lucru fără aportul dvs."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Permite aplicației să mute activităţile în prim-plan și în fundal. Aplicația poate face acest lucru fără aportul dvs."</string>
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"activare mod Maşină"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Permite aplicației să activeze modul Maşină."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"închide alte aplicații"</string>
     <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Permite aplicației să oprească procesele derulate în fundal de alte aplicații. Acest lucru poate face ca respectivele aplicații să nu mai ruleze."</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"suprapune elemente vizuale peste alte aplicații"</string>
-    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permite aplicației să suprapună elemente vizuale peste alte aplicații sau părți ale interfeței cu utilizatorul. Acestea pot interfera cu utilizarea de către dvs. a interfeței în orice aplicație sau pot schimba ceea ce credeți că vedeţi în alte aplicații."</string>
+    <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Permite aplicației să suprapună elemente vizuale peste alte aplicații sau părți ale interfeței cu utilizatorul. Acestea pot interfera cu utilizarea de către dvs. a interfeței în orice aplicație sau pot schimba ceea ce credeți că vedeți în alte aplicații."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"rulare continuă a aplicației"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea tabletei."</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"Permite aplicației să declare persistente în memorie anumite părți ale sale. Acest lucru poate limita memoria disponibilă pentru alte aplicații și poate încetini funcționarea televizorului."</string>
@@ -316,7 +316,7 @@
     <string name="permlab_getPackageSize" msgid="7472921768357981986">"măsurare spațiu de stocare al aplicației"</string>
     <string name="permdesc_getPackageSize" msgid="3921068154420738296">"Permite aplicației să preia dimensiunile codului, ale datelor și ale memoriei cache"</string>
     <string name="permlab_writeSettings" msgid="2226195290955224730">"modifică setări de sistem"</string>
-    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Permite aplicației să modifice datele din setările sistemului. Aplicaţiile rău intenţionate pot corupe configuraţia sistemului dvs."</string>
+    <string name="permdesc_writeSettings" msgid="7775723441558907181">"Permite aplicației să modifice datele din setările sistemului. Aplicațiile rău intenţionate pot corupe configuraţia sistemului dvs."</string>
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"rulează la pornire"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Permite aplicației să pornească imediat ce s-a terminat încărcarea sistemului. Din acest motiv, pornirea tabletei poate dura mai mult timp, iar rularea continuă a aplicației poate încetini dispozitivul."</string>
     <string name="permdesc_receiveBootCompleted" product="tv" msgid="4525890122209673621">"Permite aplicației să pornească imediat ce s-a terminat încărcarea sistemului. Din acest motiv, pornirea televizorului poate dura mai mult timp, iar funcționarea continuă a aplicației poate încetini televizorul."</string>
@@ -338,12 +338,12 @@
     <string name="permdesc_readCallLog" product="tv" msgid="5611770887047387926">"Permite aplicației să citească jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune, aplicațiile pot să salveze datele din jurnalul de apeluri, iar aplicațiile rău-intenționate pot permite accesul la datele din jurnalul de apeluri fără cunoștința dvs."</string>
     <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Permite aplicației să citească jurnalul de apeluri al telefonului, inclusiv datele despre apelurile primite și efectuate. Cu această permisiune aplicația salvează datele dvs. din jurnalul de apeluri, iar aplicațiile rău intenţionate pot distribui aceste date fără știrea dvs."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"scrie jurnalul de apeluri"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Permite aplicației să modifice jurnalul de apeluri al tabletei dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
     <string name="permdesc_writeCallLog" product="tv" msgid="4225034892248398019">"Permite aplicației să modifice jurnalul de apeluri al televizorului, inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău-intenționate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul de apeluri."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Permite aplicației să modifice jurnalul de apeluri al telefonului dvs., inclusiv datele despre apelurile primite sau efectuate. Aplicațiile rău intenţionate pot utiliza această permisiune pentru a șterge sau pentru a modifica jurnalul dvs. de apeluri."</string>
     <string name="permlab_bodySensors" msgid="4683341291818520277">"să acceseze senzorii corporali (cum ar fi monitoarele cardiace)"</string>
     <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite aplicației să acceseze date de la senzorii care vă monitorizează starea fizică, cum ar fi ritmul cardiac."</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar și a informaţiilor confidenţiale"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"citirea evenimentelor din calendar și a informațiilor confidenţiale"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Permite aplicației să citească toate evenimentele din calendar stocate pe tabletă, inclusiv cele ale prietenilor sau colegilor. Acest lucru poate permite aplicației să distribuie sau să salveze datele din calendar, indiferent dacă acestea sunt confidenţiale sau sensibile."</string>
     <string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"Permite aplicației să citească toate evenimentele din calendar stocate pe televizor, inclusiv cele ale prietenilor sau colegilor. Cu această permisiune, aplicația poate să permită accesul la datele din calendar sau să le salveze, indiferent dacă acestea sunt confidențiale sau sensibile."</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Permite aplicației să citească toate evenimentele din calendar stocate pe telefon, inclusiv cele ale prietenilor sau colegilor. Acest lucru poate permite aplicației să distribuie sau să salveze datele din calendar, indiferent dacă acestea sunt confidenţiale sau sensibile."</string>
@@ -354,9 +354,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>
@@ -368,7 +368,7 @@
     <string name="permlab_vibrate" msgid="7696427026057705834">"controlează vibrarea"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Permite aplicației să controleze mecanismul de vibrare."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"apelare directă numere de telefon"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite aplicației să apeleze numere de telefon fără intervenţia dvs. Acest lucru poate determina apariția unor taxe sau a unor apeluri neașteptate. Cu această permisiune aplicația nu poate apela numerele de urgenţă. Aplicaţiile rău intenţionate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Permite aplicației să apeleze numere de telefon fără intervenţia dvs. Acest lucru poate determina apariția unor taxe sau a unor apeluri neașteptate. Cu această permisiune aplicația nu poate apela numerele de urgenţă. Aplicațiile rău intenţionate pot acumula costuri prin efectuarea unor apeluri fără confirmare."</string>
     <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>
@@ -407,7 +407,7 @@
     <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>
+    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permitere recepționare difuzare multiplă Wi-Fi"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"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 tableta dvs. Această funcție utilizează mai multă energie decât modul fără difuzare multiplă."</string>
     <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>
@@ -681,7 +681,7 @@
     <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Niciun card SIM în televizor."</string>
     <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefonul nu are card SIM."</string>
     <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Introduceţi un card SIM."</string>
-    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Cardul SIM lipseşte sau nu poate fi citit. Introduceţi un card SIM."</string>
+    <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Cardul SIM lipsește sau nu poate fi citit. Introduceţi un card SIM."</string>
     <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Card SIM inutilizabil."</string>
     <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Cardul dvs. SIM este dezactivat definitiv.\n Contactaţi furnizorul de servicii wireless pentru a obţine un alt card SIM."</string>
     <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Melodia anterioară"</string>
@@ -694,21 +694,21 @@
     <string name="emergency_calls_only" msgid="6733978304386365407">"Numai apeluri de urgență"</string>
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Rețea blocată"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Cardul SIM este blocat cu codul PUK."</string>
-    <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_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">%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_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_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_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>
+    <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>
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Încercați din nou peste <xliff:g id="NUMBER">%d</xliff:g> (de) secunde."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Ați uitat modelul?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Deblocare cont"</string>
@@ -718,7 +718,7 @@
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Parolă"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Conectați-vă"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"Nume de utilizator sau parolă nevalide."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Aţi uitat numele de utilizator sau parola?\nAccesați "<b>"google.com/accounts/recovery"</b>"."</string>
+    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"Ați uitat numele de utilizator sau parola?\nAccesați "<b>"google.com/accounts/recovery"</b>"."</string>
     <string name="lockscreen_glogin_checking_password" msgid="7114627351286933867">"Se verifică..."</string>
     <string name="lockscreen_unlock_label" msgid="737440483220667054">"Deblocaţi"</string>
     <string name="lockscreen_sound_on_label" msgid="9068877576513425970">"Sunet activat"</string>
@@ -742,7 +742,7 @@
     <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"A început reordonarea widgeturilor."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Reordonarea widgeturilor s-a încheiat."</string>
     <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Widgetul <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> a fost eliminat."</string>
-    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Extindeţi zona de deblocare."</string>
+    <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Extindeți zona de deblocare."</string>
     <string name="keyguard_accessibility_slide_unlock" msgid="2959928478764697254">"Deblocare prin glisare."</string>
     <string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Deblocare cu model."</string>
     <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Deblocare facială."</string>
@@ -788,17 +788,17 @@
     <string name="autofill_area" msgid="3547409050889952423">"Zonă"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"citește marcajele și istoricul web"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite aplicației să citească istoricul tuturor adreselor URL accesate de Browser și toate marcajele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Permite aplicației să citească istoricul tuturor adreselor URL accesate de Browser și toate marcajele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"scrie în marcajele și în istoricul web"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe tabletă. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
     <string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Permite aplicației să modifice istoricul sau marcajele browserului stocate pe televizor. Cu această permisiune, aplicația poate șterge sau modifica datele din browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terţă parte sau de alte aplicații cu capacități de navigare pe web."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Permite aplicației să modifice istoricul Browserului sau marcajele stocate pe telefon. În acest fel, aplicația poate șterge sau modifica datele din Browser. Notă: această permisiune nu poate fi aplicată de browsere terță parte sau de alte aplicații cu capacități de navigare pe web."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"setează o alarmă"</string>
     <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="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>
@@ -818,8 +818,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">
@@ -875,7 +875,7 @@
     <string name="copy" msgid="2681946229533511987">"Copiați"</string>
     <string name="paste" msgid="5629880836805036433">"Inserați"</string>
     <string name="paste_as_plain_text" msgid="5427792741908010675">"Inserați ca text simplu"</string>
-    <string name="replace" msgid="5781686059063148930">"Înlocuiţi..."</string>
+    <string name="replace" msgid="5781686059063148930">"Înlocuiți..."</string>
     <string name="delete" msgid="6098684844021697789">"Ștergeți"</string>
     <string name="copyUrl" msgid="2538211579596067402">"Copiați adresa URL"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"Selectați text"</string>
@@ -895,7 +895,7 @@
     <string name="cancel" msgid="6442560571259935130">"Anulați"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
     <string name="no" msgid="5141531044935541497">"Anulați"</string>
-    <string name="dialog_alert_title" msgid="2049658708609043103">"Atenţie"</string>
+    <string name="dialog_alert_title" msgid="2049658708609043103">"Atenție"</string>
     <string name="loading" msgid="7933681260296021180">"Se încarcă…"</string>
     <string name="capital_on" msgid="1544682755514494298">"DA"</string>
     <string name="capital_off" msgid="6815870386972805832">"NU"</string>
@@ -909,12 +909,12 @@
     <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Distribuiți cu %1$s"</string>
     <string name="whichHomeApplication" msgid="4307587691506919691">"Selectați o aplicație de pe ecranul de pornire"</string>
     <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Utilizați %1$s ca ecran de pornire"</string>
-    <string name="alwaysUse" msgid="4583018368000610438">"Se utilizează în mod prestabilit pentru această acţiune."</string>
+    <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="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="noApplications" msgid="2991814273936504689">"Această acțiune nu poate fi efectuată de nicio aplicație."</string>
     <string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> s-a oprit"</string>
     <string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> s-a oprit"</string>
     <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se oprește încontinuu"</string>
@@ -939,9 +939,9 @@
     <string name="launch_warning_replace" msgid="6202498949970281412">"<xliff:g id="APP_NAME">%1$s</xliff:g> funcţionează acum."</string>
     <string name="launch_warning_original" msgid="188102023021668683">"<xliff:g id="APP_NAME">%1$s</xliff:g> a fost lansată iniţial."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Scară"</string>
-    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Afişaţi întotdeauna"</string>
+    <string name="screen_compat_mode_show" msgid="4013878876486655892">"Afișați întotdeauna"</string>
     <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Reactivați acest mod din Setări de sistem &gt; Aplicații &gt; Descărcate."</string>
-    <string name="smv_application" msgid="3307209192155442829">"Aplicaţia <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
+    <string name="smv_application" msgid="3307209192155442829">"Aplicația <xliff:g id="APPLICATION">%1$s</xliff:g> (procesul <xliff:g id="PROCESS">%2$s</xliff:g>) a încălcat propria politică StrictMode."</string>
     <string name="smv_process" msgid="5120397012047462446">"Procesul <xliff:g id="PROCESS">%1$s</xliff:g> a încălcat propria politică StrictMode."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android trece la o versiune superioară..."</string>
     <string name="android_start_title" msgid="8418054686415318207">"Android pornește..."</string>
@@ -962,11 +962,11 @@
     <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>
-    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Ton de apel silenţios setat"</string>
+    <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Ton de apel silențios setat"</string>
     <string name="volume_call" msgid="3941680041282788711">"Volum apel de intrare"</string>
     <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volum apel Bluetooth"</string>
     <string name="volume_alarm" msgid="1985191616042689100">"Volum alarmă"</string>
@@ -1010,7 +1010,7 @@
     <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Atingeți pentru setări"</string>
     <string name="accept" msgid="1645267259272829559">"Acceptaţi"</string>
     <string name="decline" msgid="2112225451706137894">"Refuzaţi"</string>
-    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitaţia a fost trimisă."</string>
+    <string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitația a fost trimisă."</string>
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Invitație pentru conectare"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"De la:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"Către:"</string>
@@ -1061,12 +1061,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Atingeți pentru mai multe opțiuni."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeți pentru a dezactiva depanarea USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Trimiteți raportul de eroare administratorului?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratorul IT a solicitat un raport de eroare pentru a remedia problemele"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ACCEPTAȚI"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUZAȚI"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Se creează un raport de eroare…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Atingeți pentru a anula"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Alegeți tastaturi"</string>
     <string name="show_ime" msgid="2506087537466597099">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string>
@@ -1075,7 +1081,7 @@
     <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Atingeți pentru a selecta un aspect de tastatură."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
+    <string name="candidates_style" msgid="4333913089637062257"><u>"candidați"</u></string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Se pregătește <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Se verifică dacă există erori"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"A fost detectat un nou <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1325,20 +1331,20 @@
     <string name="kg_login_password_hint" msgid="9057289103827298549">"Parolă"</string>
     <string name="kg_login_submit_button" msgid="5355904582674054702">"Conectați-vă"</string>
     <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_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">%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_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_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">%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_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">%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_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>
@@ -1574,9 +1580,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Dezactivat de administratorul companiei %1$s. Contactați-l pentru a afla mai multe."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Aveți mesaje noi"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Deschideți aplicația pentru SMS-uri ca să vizualizați"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Este posibil ca unele funcții să nu fie disponibile"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Atingeți pentru a continua"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil utilizator: blocat"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Unele funcții ar putea fi limitate"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Atingeți pentru a debloca"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Datele utilizatorului: blocate"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profil de serviciu blocat"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Atingeți ca să deblocați profilul de serviciu"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Conectat la <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Atingeți pentru a vedea fișierele"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fixați"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 408d443..8ed321f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Нажмите, чтобы настроить."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Нажмите, чтобы отключить отладку по USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Отправить администратору информацию об ошибке?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ваш администратор запросил информацию об ошибке. Эти данные помогут устранить неполадку."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИНЯТЬ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОТКЛОНИТЬ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Подождите…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Нажмите, чтобы отменить"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Выбрать раскладку"</string>
     <string name="show_ime" msgid="2506087537466597099">"Показывать на экране, когда физическая клавиатура включена"</string>
@@ -1542,7 +1548,7 @@
       <item quantity="other">На %d часа</item>
     </plurals>
     <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
-    <string name="zen_mode_alarm" msgid="9128205721301330797">"До следующего будильника в <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
+    <string name="zen_mode_alarm" msgid="9128205721301330797">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (будильник)"</string>
     <string name="zen_mode_forever" msgid="7420011936770086993">"Пока я не отключу"</string>
     <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Пока вы не отключите режим \"Не беспокоить\""</string>
     <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Пакет заблокирован администратором компании \"%1$s\". Обратитесь к нему за дополнительной информацией."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Новые сообщения"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Чтобы просмотреть, откройте приложение для обмена SMS"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Некоторые функции недоступны"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Нажмите, чтобы продолжить"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Профиль заблокирован"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Некоторые функции недоступны"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Нажмите для разблокировки"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Пользов. данные заблокированы"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Рабочий профиль заблокирован"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Нажмите, чтобы разблокировать раб. профиль"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Подключено к <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Нажмите, чтобы просмотреть файлы"</string>
     <string name="pin_target" msgid="3052256031352291362">"Закрепить"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 9bbab56..ee0afad 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -1055,12 +1055,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"වඩා වැඩි විකල්ප සඳහා ස්පර්ශ කරන්න."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB නිදොස්කරණය සම්බන්ධිතයි"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB නිදොස්කරණය අබල කිරීමට ස්පර්ශ කරන්න."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"පරිපාලක සමඟ දෝෂ වාර්තාවක් බෙදා ගන්නද?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"දෝෂාවේක්ෂණය සඳහා උදවු කිරීමට ඔබේ IT පරිපාලක දෝෂ වාර්තාවක් ඉල්ලා ඇත"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"පිළිගන්න"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ප්‍රතික්ෂේප කරන්න"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"දෝෂ වාර්තාවක් ගනිමින්…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"අවලංගු කිරීමට ස්පර්ශ කරන්න"</string>
     <string name="select_input_method" msgid="8547250819326693584">"යතුරු පුවරු වෙනස් කිරීම"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"යතුරු පුවරු තෝරන්න"</string>
     <string name="show_ime" msgid="2506087537466597099">"භෞතික යතුරු පුවරුව සක්‍රිය අතරතුර එය තිරය මත තබා ගන්න"</string>
@@ -1557,9 +1563,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s පරිපාලක විසින් අබල කරන ලදී. තව දැන ගැනීමට ඔවුන් අමතන්න."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"ඔබට නව පණිවිඩ තිබේ"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"බැලීමට විවෘත SMS යෙදුම විවෘත කරන්න"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"සමහර කාර්ය නොතිබිය හැකිය"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"දිගටම කරගෙන යාමට ස්පර්ශ කරන්න"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"පරිශීලක පැතිකඩ අගුලු දමා ඇත"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"ඇතැම් ක්‍රියාකාරිත්ව සීමිත විය හැකිය"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"අගුලු හැරීමට තට්ටු කරන්න"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"පරිශීලක දත්ත අගුලු දමා ඇත"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"කාර්යාල පැතිකඩ අගුලු දමා ඇත"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"කාර්යාල පැතිකඩ අගුලු හැරීමට තට්ටු කරන්න"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> වෙත සම්බන්ධ විය"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ගොනු බැලීමට තට්ටු කරන්න"</string>
     <string name="pin_target" msgid="3052256031352291362">"අමුණන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 4369374..88e3939 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Ďalšie možnosti zobrazíte klepnutím."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Klepnutím zakážete ladenie cez USB"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Zdieľať hlásenie chyby so správcom?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Správca IT si vyžiadal hlásenie chyby, aby mohol problém vyriešiť"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRIJAŤ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ODMIETNUŤ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Vytvára sa hlásenie chyby…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Dotykom zrušíte"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Vybrať klávesnicu"</string>
     <string name="show_ime" msgid="2506087537466597099">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Zakázané správcom %1$s. Ak chcete získať ďalšie informácie, kontaktujte ho."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Máte nové správy."</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Otvorte aplikáciu pre SMS a zobrazte správu"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Niektoré funkcie nemusia byť dostupné"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Pokračujte klepnutím"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil používateľa je zamknutý"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Niektoré funkcie môžu byť obmedzené"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Odomknite klepnutím"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Údaje používateľa sú uzamknuté"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Pracovný profil je uzamknutý"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Profil odomknete klepnutím"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Pripojené k zariadeniu <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Klepnutím zobrazíte súbory"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pripnúť"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 2451e3d..e821a7f 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Za več možnosti se dotaknite."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje in odpravljanje napak USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Želite skrbniku poslati poročilo o napakah?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Skrbnik IT je zahteval poročilo o napakah za pomoč pri odpravljanju napak"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"SPREJMEM"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"NE SPREJMEM"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Zajemanje poročila o napakah …"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Če želite prekiniti, se dotaknite"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Sprememba tipkovnice"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Izbira tipkovnic"</string>
     <string name="show_ime" msgid="2506087537466597099">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Onemogočil skrbnik %1$s. Za več informacij se obrnite nanj."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Imate nova sporočila."</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Za ogled odprite aplikacijo za SMS-je"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Nek. funk. morda niso na voljo"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Dotaknite se za nadaljevanje"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profil uporabnika zaklenjen"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Nekatere funkcije bodo omejene"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Dotaknite se, da odklenete"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Uporabniški podatki zaklenjeni"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Delovni profil je zaklenjen"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Dotaknite se za odkl. del. pr."</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Vzpostavljena povezava z napravo <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dotaknite se, če si želite ogledati datoteke"</string>
     <string name="pin_target" msgid="3052256031352291362">"Pripenjanje"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 70164be..ed2c066 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Prek për më shumë opsione."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Prek për të çaktivizuar korrigjimin e gabimeve të USB-së."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ndaje raportin e defekteve në kod me administratorin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratori i teknologjisë së informacionit kërkoi një raport të defekteve në kod për të ndihmuar me zgjidhjen e problemeve"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"PRANO"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REFUZO"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Po merret raporti i defekteve në kod…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Prek për ta anuluar"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Ndërro tastierë"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Zgjidh tastierat"</string>
     <string name="show_ime" msgid="2506087537466597099">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Çaktivizuar nga administratori i %1$s. Kontaktoje për të mësuar më shumë."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Ke mesazhe të reja"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Hap aplikacionin SMS për ta parë"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Disa funksione mund të mos jenë të disponueshme"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Preke për të vazhduar"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Profili i përdoruesit i kyçur"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Disa funksione mund të jenë të kufizuara"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Trokit për të shkyçur"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Të dhënat e përdoruesit të kyçura"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profili i punës është i kyçur"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Trokit për ta shkyçur profilin e punës"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"U lidh me <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Trokit për të parë skedarët"</string>
     <string name="pin_target" msgid="3052256031352291362">"Gozhdo"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index a62d7d6..2212c98 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1061,12 +1061,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Додирните за још опција."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Желите ли да делите извештај о грешци са администратором?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ИТ администратор је затражио извештај о грешци ради лакшег решавања проблема"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИХВАТИ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ОДБИЈ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Извештај о грешци се генерише…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Додирните да бисте отказали"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Промените тастатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Изаберите тастатуре"</string>
     <string name="show_ime" msgid="2506087537466597099">"Задржи га на екрану док је физичка тастатура активна"</string>
@@ -1574,9 +1580,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Онемогућио је администратор компаније %1$s. Контактирајте га да бисте сазнали више."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Имате нове поруке"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Отворите апликацију за SMS да бисте прегледали"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Неке функције нису доступне"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Додирните да бисте наставили"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Профил корисника је закључан"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Неке функције су можда ограничене"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Додирните да бисте откључали"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Подаци корисника су закључани"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Профил за Work је закључан"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Додиром откљ. профил за Work"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Повезано је са производом <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Додирните за преглед датотека"</string>
     <string name="pin_target" msgid="3052256031352291362">"Закачи"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f90f95c..8483eaa 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Visa fler alternativ genom att trycka."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryck om du vill inaktivera USB-felsökning."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Vill du dela en felrapport med administratören?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"IT-administratören har bett om en felrapport som hjälp vid felsökningen."</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"GODKÄNN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"AVVISA"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Felrapporten överförs …"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Tryck här om du vill avbryta"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Byt tangentbord"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Välj tangentbord"</string>
     <string name="show_ime" msgid="2506087537466597099">"Ha kvar den på skärmen när det fysiska tangentbordet används"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Inaktiverat av administratören för %1$s. Kontakta administratören om du vill veta mer."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Du har nya meddelanden"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Öppna sms-appen och visa meddelandet"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Vissa funktioner är inte tillgängliga"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Tryck om du vill fortsätta"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Användarprofilen är låst"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Vissa funktioner är begränsade"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Tryck om du vill låsa upp"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Användaruppgifterna är låsta"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Jobbprofilen är låst"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Tryck och lås upp jobbprofilen"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Ansluten till <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Filerna visas om du trycker här"</string>
     <string name="pin_target" msgid="3052256031352291362">"Fäst"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 856484c..8564764 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1055,12 +1055,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Gusa kwa chaguo zaidi."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Utatuaji wa USB umeunganishwa"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Gusa ili uzime utatuaji wa USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ungependa kushiriki ripoti ya hitilafu na msimamizi?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Msimamizi wako wa IT ameomba ripoti ya hitilafu ili kusaidia katika utatuzi"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"KUBALI"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"KATAA"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Inatayarisha ripoti ya hitilafu…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Gusa ili ufute"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Badilisha kibodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chagua kibodi"</string>
     <string name="show_ime" msgid="2506087537466597099">"Iweke kwenye skrini wakati kibodi inapotumika"</string>
@@ -1557,9 +1563,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Imezimwa na msimamizi wa %1$s. Wasiliana naye ili upate maelezo zaidi."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Una ujumbe mpya"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Fungua programu ya SMS ili uweze kuangalia"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Huenda baadhi ya vipengele visipatikane"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Gusa ili uendelee"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Wasifu wa mtumiaji umefungwa"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Huenda baadhi ya utendaji ukawa vikwazo"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Gonga ili ufungue"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Data ya mtumiaji imefungwa"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Wasifu wa kazini umefungwa"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Gonga ili ufungue wasifu wa kazini"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Imeunganishwa na <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Gonga ili uangalie faili"</string>
     <string name="pin_target" msgid="3052256031352291362">"Bandika"</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index d7e96e8..b5f3673 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1031,7 +1031,7 @@
     <string name="sim_added_title" msgid="3719670512889674693">"சிம் கார்டு சேர்க்கப்பட்டது"</string>
     <string name="sim_added_message" msgid="7797975656153714319">"செல்லுலார் நெட்வொர்க்கை அணுக உங்கள் சாதனத்தை மறுதொடக்கம் செய்யவும்."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"மறுதொடக்கம்"</string>
-    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"புதிய சிம் சரியாக இயங்குவதற்கு, நீங்கள் பயன்படுத்தும் மொபைல் நிறுவனத்திலிருந்து பயன்பாட்டை நிறுவி, திறக்கவும்."</string>
+    <string name="carrier_app_dialog_message" msgid="7066156088266319533">"புதிய சிம் சரியாக இயங்குவதற்கு, நீங்கள் பயன்படுத்தும் மொபைல் நிறுவனத்திலிருந்து ஒரு பயன்பாட்டை நிறுவி, திறக்க வேண்டும்."</string>
     <string name="carrier_app_dialog_button" msgid="7900235513678617329">"பயன்பாட்டைப் பெறுக"</string>
     <string name="carrier_app_dialog_not_now" msgid="6361378684292268027">"இப்போது வேண்டாம்"</string>
     <string name="carrier_app_notification_title" msgid="8921767385872554621">"புதிய சிம் செருகப்பட்டது"</string>
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"கூடுதல் விருப்பங்களுக்காகத் தொடவும்."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB பிழைத்திருத்தத்தை முடக்க, தொடவும்."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"பிழை அறிக்கையை நிர்வாகியுடன் பகிரவா?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"பிழைகாண்பதற்கு உதவ, உங்கள் ஐடி நிர்வாகி பிழை அறிக்கையைக் கோரியுள்ளார்"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"சரி"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"வேண்டாம்"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"பிழை அறிக்கையை எடுக்கிறது…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"ரத்துசெய்ய, தொடவும்"</string>
     <string name="select_input_method" msgid="8547250819326693584">"விசைப்பலகையை மாற்று"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"விசைப்பலகைகளைத் தேர்வுசெய்க"</string>
     <string name="show_ime" msgid="2506087537466597099">"கைமுறை விசைப்பலகை இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s நிர்வாகி முடக்கியுள்ளார். மேலும் அறிய, அவரைத் தொடர்புகொள்ளவும்."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"புதிய செய்திகள் வந்துள்ளன"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"பார்க்க, SMS பயன்பாட்டைத் திறக்கவும்"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"சில செயல்பாடு கிடைக்காமல் போகலாம்"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"தொடர, தொடவும்"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"பயனர் சுயவிவரம் பூட்டப்பட்டது"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"சில செயல்பாடு வரம்பிடப்பட்டிருக்கலாம்"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"திறக்க, தட்டவும்"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"பயனர் தரவு பூட்டப்பட்டது"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"பணி சுயவிவரம் பூட்டியுள்ளது"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"பணி சுயவிவரத்தை திறக்க, தட்டுக"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> உடன் இணைக்கப்பட்டது"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"கோப்புகளைப் பார்க்க, தட்டவும்"</string>
     <string name="pin_target" msgid="3052256031352291362">"பின் செய்"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 6d42955..e7d0fa8 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"మరిన్ని ఎంపికల కోసం తాకండి."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB డీబగ్గింగ్‌ను నిలిపివేయడానికి తాకండి."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"బగ్ నివేదికను నిర్వాహకులకు భాగస్వామ్యం చేయాలా?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"మీ ఐటి నిర్వాహకులు సమస్య పరిష్కారాన్ని కనుగొనడంలో సహాయం కోసం బగ్ నివేదికను అభ్యర్థించారు"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ఆమోదిస్తున్నాను"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"తిరస్కరిస్తున్నాను"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"బగ్ నివేదికను తీస్తోంది…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"రద్దు చేయడానికి తాకండి"</string>
     <string name="select_input_method" msgid="8547250819326693584">"కీబోర్డ్‌ను మార్చు"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"కీబోర్డ్‌లను ఎంచుకోండి"</string>
     <string name="show_ime" msgid="2506087537466597099">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్‌పై ఉంచుతుంది"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$sని నిర్వాహకుడు నిలిపివేసారు. మరింత తెలుసుకోవడానికి వారిని సంప్రదించండి."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"మీకు కొత్త సందేశాలు ఉన్నాయి"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"వీక్షించడానికి SMS అనువర్తనాన్ని తెరవండి"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"కొన్ని విధులు ఉండకపోవచ్చు"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"కొనసాగడానికి తాకండి"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"వినియోగ. ప్రొఫైల్ లాక్ అయింది"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"కొంత కార్యాచరణ పరిమితం కావచ్చు"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"అన్‌లాక్ చేయడానికి నొక్కండి"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"వినియోగదారు డేటా లాక్ అయ్యింది"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"కార్యాలయ ప్రొఫైల్ లాక్ అయింది"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"కార్యాలయ ప్రొఫైల్ అన్‌లాక్ చేయుటకు నొక్కండి"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>కి కనెక్ట్ చేయబడింది"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"ఫైల్‌లను వీక్షించడానికి నొక్కండి"</string>
     <string name="pin_target" msgid="3052256031352291362">"పిన్ చేయి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 15cd2ff..8486c7be 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"ต้องการแชร์รายงานข้อบกพร่องกับผู้ดูแลระบบไหม"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"ผู้ดูแลระบบไอทีของคุณขอรายงานข้อบกพร่องเพื่อช่วยในการแก้ไขปัญหา"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ยอมรับ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ปฏิเสธ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"กำลังสร้างรายงานข้อบกพร่อง…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"แตะเพื่อยกเลิก"</string>
     <string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"เลือกแป้นพิมพ์"</string>
     <string name="show_ime" msgid="2506087537466597099">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"ผู้ดูแลระบบ %1$s ได้ปิดใช้แล้ว โปรดสอบถามข้อมูลเพิ่มเติมจากเขา"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"คุณมีข้อความใหม่"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"เปิดแอป SMS เพื่อดู"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"บางฟังก์ชันอาจไม่พร้อมใช้งาน"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"แตะเพื่อดำเนินการต่อ"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"โปรไฟล์ผู้ใช้ถูกล็อก"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"อาจมีข้อจำกัดในบางฟังก์ชัน"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"แตะเพื่อปลดล็อก"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"ล็อกข้อมูลผู้ใช้อยู่"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"โปรไฟล์งานถูกล็อก"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"แตะเพื่อปลดล็อกโปรไฟล์งาน"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"เชื่อมต่อ <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"แตะเพื่อดูไฟล์"</string>
     <string name="pin_target" msgid="3052256031352291362">"ปักหมุด"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index af36041..70b32c7 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Pindutin para sa higit pang mga opsyon."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Pindutin upang i-disable ang pagde-debug ng USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Ibahagi ang ulat ng bug sa admin?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Humiling ang iyong admin ng IT ng ulat ng bug upang makatulong sa pag-troubleshoot"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"TANGGAPIN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TANGGIHAN"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Kinukuha ang ulat ng bug…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Pindutin upang kanselahin"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Baguhin ang keyboard"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Pumili ng mga keyboard"</string>
     <string name="show_ime" msgid="2506087537466597099">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Na-disable ng administrator ng %1$s. Makipag-ugnayan sa administrator upang matuto nang higit pa."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Mayroon kang mga bagong mensahe"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Buksan ang SMS app upang tingnan"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Maaaring hindi available ang ilang function"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Pindutin upang magpatuloy"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Naka-lock ang profile ng user"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Limitado ilang functionality"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Mag-tap upang ma-unlock"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Naka-lock ang data ng user"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Profile sa trabaho, naka-lock"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"I-unlock ang profile sa trabaho, i-tap"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Nakakonekta sa <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"I-tap upang makita ang mga file"</string>
     <string name="pin_target" msgid="3052256031352291362">"I-pin"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 6a4c7df..ee55277 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Daha fazla seçenek için dokunun."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Hata raporu yöneticiyle paylaşılsın mı?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"BT yöneticiniz, sorun gidermeye yardımcı olması için bir hata raporu istedi"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"KABUL ET"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"REDDET"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Hata raporu alınıyor…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"İptal etmek için dokunun"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klavyeyi değiştir"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klavyeyi seç"</string>
     <string name="show_ime" msgid="2506087537466597099">"Fiziksel klavye etkin durumdayken ekranda tut"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s yöneticisi tarafından devre dışı bırakıldı. Daha fazla bilgi edinmek için kendileriyle iletişime geçin."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Yeni mesajlarınız var"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Görüntülemek için SMS uygulamasını açın"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Bazı işlevler kullanılamayabilir"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Devam etmek için dokunun"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Kullanıcı profili kilitli"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Bazı işlevler sınırlı olabilir"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Kilidi açmak için dokunun"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Kullanıcı verileri kilitlendi"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"İş profili kilitlendi"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"İş profilinin kilidini açmak için hafifçe dokunun"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> cihazına bağlandı"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Dosyaları görüntülemek için hafifçe dokunun"</string>
     <string name="pin_target" msgid="3052256031352291362">"Sabitle"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 3eb3fd8..f546d56 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1069,12 +1069,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Торкніться, щоб побачити більше опцій."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Надіслати адміністратору повідомлення про помилку?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Ваш ІТ-адміністратор просить надіслати повідомлення про помилку, щоб вирішити проблему"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"ПРИЙНЯТИ"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"ВІДХИЛИТИ"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Створюється повідомлення про помилку…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Торкніться, щоб скасувати"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Змінити клавіатуру"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Вибрати клавіатури"</string>
     <string name="show_ime" msgid="2506087537466597099">"Утримуйте на екрані, коли активна фізична клавіатура"</string>
@@ -1593,9 +1599,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Вимкнув адміністратор %1$s. Зв’яжіться з ним, щоб дізнатися більше."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"У вас є нові повідомлення"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Щоб переглянути, відкрийте додаток для SMS"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Деякі функції можуть бути недоступні"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Торкніться, щоб продовжити"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Профіль користувача блокується"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Деякі функції можуть не працювати"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Торкніться, щоб розблокувати"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Дані користувача заблоковано"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Робочий профіль заблоковано"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Торкніться, щоб розблокувати"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Під’єднано до пристрою <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Торкніться, щоб переглянути файли"</string>
     <string name="pin_target" msgid="3052256031352291362">"Закріпити"</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 48877b4..80d4c85 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"مزید اختیارات کیلئے ٹچ کریں۔"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"‏USB ڈیبگ کرنا مربوط ہو گیا"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"‏USB ڈیبگنگ کو غیر فعال کرنے کیلئے ٹچ کریں۔"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"منتظم کے ساتھ بگ رپورٹ کا اشتراک کریں؟"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"‏آپ کے IT منتظم نے ٹربل شوٹ میں مدد کیلئے ایک بگ رپورٹ کی درخواست کی"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"قبول کریں"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"مسترد کریں"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"بگ رپورٹ لی جا رہی ہے…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"منسوخ کرنے کیلئے ٹچ کریں"</string>
     <string name="select_input_method" msgid="8547250819326693584">"کی بورڈ تبدیل کریں"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"کی بورڈز منتخب کریں"</string>
     <string name="show_ime" msgid="2506087537466597099">"‏جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"‏%1$s منتظم کی جانب سے غیر فعال کر دیا گیا۔ مزید جاننے کیلئے ان سے رابطہ کریں۔"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"آپ کے پاس نئے پیغامات ہیں"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"‏دیکھنے کیلئے SMS ایپ کھولیں"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"ممکن ہے کچھ فنکشز دستیاب نہ ہوں"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"جاری رکھنے کیلئے تھپتھپائیں"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"صارف پروفائل مقفل ہو گئی"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"کچھ فعالیت محدود ہو سکتی ہے"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"غیرمقفل کرنے کیلئے تھپتھپائیں"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"صارف کا ڈیٹا مقفل ہے"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"دفتری پروفائل مقفل ہے"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"دفتری پروفائل غیر مقفل کرنے کیلئے تھپتھپائیں"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> سے منسلک"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"فائلوں کو دیکھنے کیلئے تھپتھپائیں"</string>
     <string name="pin_target" msgid="3052256031352291362">"پن کریں"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index cc60c8c..8b5e230 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -864,7 +864,7 @@
     <string name="Midnight" msgid="5630806906897892201">"Yarim tun"</string>
     <string name="elapsed_time_short_format_mm_ss" msgid="4431555943828711473">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
     <string name="elapsed_time_short_format_h_mm_ss" msgid="1846071997616654124">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
-    <string name="selectAll" msgid="6876518925844129331">"Barchasini tanlash"</string>
+    <string name="selectAll" msgid="6876518925844129331">"Hammasini belgilash"</string>
     <string name="cut" msgid="3092569408438626261">"Kesish"</string>
     <string name="copy" msgid="2681946229533511987">"Nusxa olish"</string>
     <string name="paste" msgid="5629880836805036433">"Joylash"</string>
@@ -977,12 +977,12 @@
     <string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtonlar"</string>
     <string name="ringtone_unknown" msgid="5477919988701784788">"Noma’lum rington"</string>
     <plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
-      <item quantity="other">Wi-Fi tarmoqlari mavjud emas</item>
-      <item quantity="one">Wi-Fi tarmog‘i mavjud emas</item>
+      <item quantity="other">Wi-Fi tarmoqlari aniqlandi</item>
+      <item quantity="one">Wi-Fi tarmog‘i aniqlandi</item>
     </plurals>
     <plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
-      <item quantity="other">Ochiq Wi-Fi tarmoqlari mavjud</item>
-      <item quantity="one">Ochiq Wi-Fi tarmog‘i mavjud</item>
+      <item quantity="other">Ochiq Wi-Fi tarmoqlari aniqlandi</item>
+      <item quantity="one">Ochiq Wi-Fi tarmog‘i aniqlandi</item>
     </plurals>
     <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi tarmoqqa kirish"</string>
     <string name="network_available_sign_in" msgid="1848877297365446605">"Tarmoqqa kirish"</string>
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Sozlash uchun bosing."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Administrator bilan xatoliklar hisoboti ulashilsinmi?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Administratoringiz nosozliklarni tuzatish uchun xatoliklar hisobotini so‘ramoqda"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"QABUL QILISH"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"RAD ETISH"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Xatoliklar hisoboti olinmoqda…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Bekor qilish uchun bosing"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string>
     <string name="show_ime" msgid="2506087537466597099">"Tashqi klaviaturadan foydalanilayotganda buni ekranda saqlab turish"</string>
@@ -1153,7 +1159,7 @@
     <string name="submit" msgid="1602335572089911941">"Jo‘natish"</string>
     <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Mashina usuli yoqilgan"</string>
     <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Avtomashina rejimidan chiqish uchun bosing."</string>
-    <string name="tethered_notification_title" msgid="3146694234398202601">"Modem yoki ulanish nuqtasi - faol"</string>
+    <string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
     <string name="tethered_notification_message" msgid="6857031760103062982">"Sozlash uchun bosing."</string>
     <string name="back_button_label" msgid="2300470004503343439">"Orqaga"</string>
     <string name="next_button_label" msgid="1080555104677992408">"Keyingi"</string>
@@ -1167,7 +1173,7 @@
     <string name="action_mode_done" msgid="7217581640461922289">"Tayyor"</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB xotirasi tozalanmoqda…"</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD xotira kartasi tozalanmoqda…"</string>
-    <string name="share" msgid="1778686618230011964">"Bo‘lishish"</string>
+    <string name="share" msgid="1778686618230011964">"Yuborish"</string>
     <string name="find" msgid="4808270900322985960">"Topish"</string>
     <string name="websearch" msgid="4337157977400211589">"Veb qidiruv"</string>
     <string name="find_next" msgid="5742124618942193978">"Keyingisini topish"</string>
@@ -1212,8 +1218,8 @@
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Kiritish"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Ilovani tanlang"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ishga tushmadi"</string>
-    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bo‘lishish:"</string>
-    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> bilan bo‘lishish"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ruxsat berish"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ilovasiga ruxsat berish"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Surish uchun dastak. Bosing va ushlab turing."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Qulfdan chiqarish uchun silang."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Parol kalitlarini eshitish uchun garnitura ulang."</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"%1$s administratori tomonidan o‘chirilgan. Batafsil ma’lumot uchun bog‘laning."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Sizga yangi SMS keldi"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Ko‘rish uchun SMS ilovasini oching"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Ayrim funksiyalar mavjud bo‘lmasligi mumkin"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Davom etish uchun bosing"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Foydalanuvchi profili yopiq"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Ba’zi funksiyalar cheklanishi m-n"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Qulfni ochish uchun bosing"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Foydalanuvchi ma’lumotlari yopiq"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Ishchi profil yopiq"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Qulfini ochish uchun bosing"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"<xliff:g id="PRODUCT_NAME">%1$s</xliff:g> qurilmasiga ulandi"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Fayllarni ko‘rish uchun bosing"</string>
     <string name="pin_target" msgid="3052256031352291362">"Qadash"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 44e76b5..7d4e43f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Chạm để có các tùy chọn khác."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Chạm để vô hiệu hóa gỡ lỗi USB."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Chia sẻ báo cáo lỗi với quản trị viên?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Quản trị viên CNTT của bạn đã yêu cầu báo cáo lỗi để giúp khắc phục sự cố"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"CHẤP NHẬN"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"TỪ CHỐI"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Đang thực hiện báo cáo lỗi…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Chạm để hủy"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Thay đổi bàn phím"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Chọn bàn phím"</string>
     <string name="show_ime" msgid="2506087537466597099">"Tiếp tục sử dụng ứng dụng trên màn hình trong khi bàn phím thực đang hoạt động"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Đã bị quản trị viên %1$s tắt. Hãy liên hệ với quản trị viên để tìm hiểu thêm."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Bạn có tin nhắn mới"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Mở ứng dụng SMS để xem"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Một số c.năng có thể ko k.dụng"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Chạm để tiếp tục"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Đã khóa hồ sơ người dùng"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Một số chức năng có thể bị hạn chế"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Nhấn để mở khóa"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Đã khóa dữ liệu người dùng"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Đã khóa hồ sơ công việc"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Nhấn để mở khóa hồ sơ công việc"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Đã kết nối với <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Nhấn để xem tệp"</string>
     <string name="pin_target" msgid="3052256031352291362">"Ghim"</string>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 63df5be..61753b1 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -25,6 +25,7 @@
     <style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Micro.Dialog" />
     <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Micro.Dialog" />
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Micro.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Settings" parent="Theme.Micro" />
     <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Micro" />
 
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index a84fc26..b8ea898 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"触摸以查看更多选项。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用USB调试。"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要与管理员分享错误报告吗?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理员已请求获取错误报告,以便帮助您排查问题"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒绝"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在生成错误报告…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"触摸可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"更改键盘"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"选择键盘"</string>
     <string name="show_ime" msgid="2506087537466597099">"连接到实体键盘时使其在屏幕上保持显示状态"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"该软件包已被%1$s管理员禁用。请与管理员联系以了解详情。"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"您有新消息"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"打开短信应用查看"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"部分功能可能无法使用"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"触摸即可继续"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"用户个人资料已锁定"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"部分功能可能会受到限制"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"点按即可解锁"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"用户数据已锁定"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"工作资料已锁定"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"点按即可解锁工作资料"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已连接到<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"点按即可查看文件"</string>
     <string name="pin_target" msgid="3052256031352291362">"固定"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 1680259..5464fbf 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"輕觸以瀏覽更多選項。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要與管理員分享錯誤報告嗎?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告,以協助解決疑難"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒絕"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在取得錯誤報告…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
     <string name="show_ime" msgid="2506087537466597099">"在實體鍵盤處於連接狀態時保持顯示"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"「%1$s」管理員已停用此套件。請與管理員聯絡以瞭解詳情。"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"您有新的訊息"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"開啟短訊應用程式查看內容"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"部分功能可能無法使用"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"輕觸即可繼續"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"使用者個人檔案目前處於鎖定狀態"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"部分功能可能會受到限制"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"輕按即可解鎖"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"使用者資料已上鎖"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"工作設定檔已上鎖"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"輕按即可將工作設定檔解鎖"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"輕按即可查看檔案"</string>
     <string name="pin_target" msgid="3052256031352291362">"固定"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 59c893c..ff6dc23 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"輕觸即可顯示更多選項。"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"要與管理員分享錯誤報告嗎?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"您的 IT 管理員要求您提供錯誤報告以便排解問題"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"接受"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"拒絕"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"正在接收錯誤報告…"</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"輕觸即可取消"</string>
     <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string>
     <string name="show_ime" msgid="2506087537466597099">"有連接的實體鍵盤時保持顯示"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"這個套件已由「%1$s」管理員停用。請與對方聯絡以瞭解詳情。"</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"您有新訊息"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"開啟簡訊應用程式來查看內容"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"部分功能可能無法使用"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"輕觸即可繼續作業"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"使用者個人資料目前處於鎖定狀態"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"部分功能可能受到鎖定"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"輕按即可解鎖"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"使用者資料已鎖定"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Work 設定檔目前處於鎖定狀態"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"輕按即可將 Work 設定檔解鎖"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"已連線至 <xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"輕觸即可查看檔案"</string>
     <string name="pin_target" msgid="3052256031352291362">"固定"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 9fd4725..6793a9a 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1053,12 +1053,18 @@
     <string name="usb_notification_message" msgid="7347368030849048437">"Thinta ukuze uthole ezinye izinketho."</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Thinta ukwenza ukuthi ukudibhaga kwe-USB kungasebenzi."</string>
-    <string name="share_remote_bugreport_notification_title" msgid="3116061729914615290">"Yabelana ngombiko wesiphazamisi nomqondisi?"</string>
-    <string name="share_remote_bugreport_notification_message" msgid="1310517845557771773">"Umqondisi wakho we-IT ucele umbiko wesiphazamisi ukuze asize ukuxazulula inkinga"</string>
+    <!-- no translation found for share_remote_bugreport_notification_title (4987095013583691873) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_title (7692523022154791488) -->
+    <skip />
+    <!-- no translation found for share_remote_bugreport_notification_message (8643704339578372992) -->
+    <skip />
+    <!-- no translation found for share_finished_remote_bugreport_notification_message (4627312060769912353) -->
+    <skip />
+    <!-- no translation found for sharing_remote_bugreport_notification_message (673106383408474893) -->
+    <skip />
     <string name="share_remote_bugreport_notification_accept" msgid="8203856129078669677">"YAMUKELA"</string>
     <string name="share_remote_bugreport_notification_decline" msgid="6337969352057443969">"YENQABA"</string>
-    <string name="remote_bugreport_progress_notification_title" msgid="2785600634417078622">"Ithatha umbiko wesiphazamisi..."</string>
-    <string name="remote_bugreport_progress_notification_message_can_cancel" msgid="5743435483005099451">"Thinta ukuze ukhansele"</string>
     <string name="select_input_method" msgid="8547250819326693584">"Shintsha ikhibhodi"</string>
     <string name="configure_input_methods" msgid="4769971288371946846">"Khetha amakhibhodi"</string>
     <string name="show_ime" msgid="2506087537466597099">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string>
@@ -1555,9 +1561,11 @@
     <string name="suspended_package_message" msgid="6341091587106868601">"Ikhutshazwe umlawuli we-%1$s. Xhumana nabo ukuze ufunde kabanzi."</string>
     <string name="new_sms_notification_title" msgid="8442817549127555977">"Unemilayezo emisha"</string>
     <string name="new_sms_notification_content" msgid="7002938807812083463">"Vula uhlelo lokusebenza lwe-SMS ukuze ubuke"</string>
-    <string name="user_encrypted_title" msgid="7664361246988454307">"Eminye imisebenzi ingahle ingatholakali"</string>
-    <string name="user_encrypted_message" msgid="7504541494700807850">"Thinta ukuze uqhubeke"</string>
-    <string name="user_encrypted_detail" msgid="979981584766912935">"Iphrofayela yomsebenzisi ikhiyiwe"</string>
+    <string name="user_encrypted_title" msgid="9054897468831672082">"Okunye ukusebenza kungakhawulelwe"</string>
+    <string name="user_encrypted_message" msgid="4923292604515744267">"Thepha ukuze uvule"</string>
+    <string name="user_encrypted_detail" msgid="5708447464349420392">"Idatha yomsebenzisi ikhiyiwe"</string>
+    <string name="profile_encrypted_detail" msgid="3700965619978314974">"Iphrofayela yomsebenzi ikhiyiwe"</string>
+    <string name="profile_encrypted_message" msgid="6964994232310195874">"Thepha ukuze uvule iphrofayela yomsebenzi"</string>
     <string name="usb_mtp_launch_notification_title" msgid="8359219638312208932">"Kuxhumekile ku-<xliff:g id="PRODUCT_NAME">%1$s</xliff:g>"</string>
     <string name="usb_mtp_launch_notification_description" msgid="8541876176425411358">"Thepha ukuze ubuke onke amafayela"</string>
     <string name="pin_target" msgid="3052256031352291362">"Phina"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b9d8661..4480944 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4430,7 +4430,9 @@
              inside of its frozen icicle in addition to meta-data such as
              the current cursor position.  By default this is disabled;
              it can be useful when the contents of a text view is not stored
-             in a persistent place such as a content provider. -->
+             in a persistent place such as a content provider. For
+             {@link android.widget.EditText} it is always enabled, regardless
+             of the value of the attribute. -->
         <attr name="freezesText" format="boolean" />
         <!-- If set, causes words that are longer than the view is wide
              to be ellipsized instead of broken in the middle.
@@ -5028,7 +5030,7 @@
         <attr name="firstDayOfWeek" format="integer" />
         <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="minDate" />
-        <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
+        <!-- The maximal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="maxDate" />
         <!-- The text appearance for the month and year in the calendar header. -->
         <attr name="monthTextAppearance" format="reference" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3a5336c..f91bcd0 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -429,8 +429,10 @@
          sets. -->
     <attr name="multiArch" format ="boolean" />
 
-    <!-- Specify abiOverride for multiArch application. -->
-    <attr name="abiOverride" />
+    <!-- Specify whether the 32 bit version of the ABI should be used in a
+         multiArch application. If both abioverride flag (i.e. using abi option of abd install)
+         and use32bitAbi are used, then use32bit is ignored.-->
+    <attr name="use32bitAbi" />
 
     <!-- Specify whether a component is allowed to have multiple instances
          of itself running in different processes.  Use with the activity
@@ -1423,22 +1425,24 @@
         <attr name="reqFiveWayNav" />
     </declare-styleable>
 
-    <!-- The <code>uses-feature</code> tag specifies
-         a specific feature used by the application.
-         For example an application might specify that it requires
-         specific version of OpenGL. Multiple such attribute
-         values can be specified by the application.
+    <!-- The <code>uses-feature</code> tag specifies a specific device
+         hardware or software feature used by the application. For
+         example an application might specify that it requires
+         a camera. Multiple attribute values can be specified by the
+         application.
 
          <p>This appears as a child tag of the root
          {@link #AndroidManifest manifest} tag. -->
     <declare-styleable name="AndroidManifestUsesFeature" parent="AndroidManifest">
+        <!-- The name of the feature that is being used. -->
+        <attr name="name" />
+        <!-- The version of the feature that is being used. -->
+        <attr name="version" format="integer" />
         <!-- The GLES driver version number needed by an application.
              The higher 16 bits represent the major number and the lower 16 bits
              represent the minor number. For example for GL 1.2 referring to
              0x00000102, the actual value should be set as 0x00010002. -->
-        <attr name="glEsVersion" format="integer"/>
-        <!--  The name of the feature that is being used. -->
-        <attr name="name" />
+        <attr name="glEsVersion" format="integer" />
         <!--  Specify whether this feature is required for the application.
               The default is true, meaning the application requires the
               feature, and does not want to be installed on devices that
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 507925b..016ed60 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -998,7 +998,6 @@
             0 - Nothing
             1 - Recent apps view in SystemUI
             2 - Launch assist intent
-            3 - Start picture-in-picture (PIP) or launch PIP UI
          This needs to match the constants in
          policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
     -->
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 96a81d1..2fe4f66 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -82,6 +82,9 @@
     <dimen name="text_size_medium_material">18sp</dimen>
     <dimen name="text_size_small_material">14sp</dimen>
 
+    <dimen name="text_edit_floating_toolbar_elevation">2dp</dimen>
+    <dimen name="text_edit_floating_toolbar_margin">20dp</dimen>
+
     <dimen name="floating_window_z">16dp</dimen>
     <dimen name="floating_window_margin_left">16dp</dimen>
     <dimen name="floating_window_margin_top">8dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5c5aff0..894fd37 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2696,10 +2696,11 @@
     <public type="attr" name="endX" />
     <public type="attr" name="endY" />
     <public type="attr" name="offset" />
-    <public type="attr" name="abiOverride" />
+    <public type="attr" name="use32bitAbi" />
     <public type="attr" name="bitmap" />
     <public type="attr" name="hotSpotX" />
     <public type="attr" name="hotSpotY" />
+    <public type="attr" name="version" />
 
     <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
     <public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 36e79f2..68afaba 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2920,17 +2920,19 @@
     <string name="adb_active_notification_message">Touch to disable USB debugging.</string>
 
     <!-- Title of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. -->
-    <string name="share_remote_bugreport_notification_title">Share bug report with admin?</string>
+    <string name="share_remote_bugreport_notification_title">Share bug report?</string>
+    <!-- Title of notification shown to indicate that bug report is still being collected after sharing was accepted. -->
+    <string name="sharing_remote_bugreport_notification_title">Sharing bug report</string>
     <!-- Message of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. -->
-    <string name="share_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot</string>
+    <string name="share_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared. This may temporarily slow down your device.</string>
+    <!-- Message of notification shown to ask for user consent for sharing a bugreport that was requested remotely by the IT administrator. -->
+    <string name="share_finished_remote_bugreport_notification_message">Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.</string>
+    <!-- Message of notification shown to shown to indicate that bug report is still being collected after sharing was accepted. -->
+    <string name="sharing_remote_bugreport_notification_message">This may temporarily slow down your device</string>
     <!-- Acceptance label of notification shown to ask for user consent for sharing the remote bugreport. -->
     <string name="share_remote_bugreport_notification_accept">ACCEPT</string>
     <!-- Decline label of notification shown to ask for user consent for sharing the remote bugreport. -->
     <string name="share_remote_bugreport_notification_decline">DECLINE</string>
-    <!-- Title of notification shown for remote bugreport progress. -->
-    <string name="remote_bugreport_progress_notification_title">Taking bug report\u2026</string>
-    <!-- Message of notification shown for remote bugreport progress. User can cancel the bugreport -->
-    <string name="remote_bugreport_progress_notification_message_can_cancel">Touch to cancel</string>
 
     <!-- Used to replace %s in urls retreived from the signin server with locales.  For Some        -->
     <!-- devices we don't support all the locales we ship to and need to replace the '%s' with a    -->
@@ -4204,11 +4206,16 @@
     <string name="new_sms_notification_content">Open SMS app to view</string>
 
     <!-- Notification title shown when user profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
-    <string name="user_encrypted_title">Some functions might not be available</string>
+    <string name="user_encrypted_title">Some functionality may be limited</string>
     <!-- Notification message shown when user profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
-    <string name="user_encrypted_message">Touch to continue</string>
+    <string name="user_encrypted_message">Tap to unlock</string>
     <!-- Notification detail shown when user profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
-    <string name="user_encrypted_detail">User profile locked</string>
+    <string name="user_encrypted_detail">User data locked</string>
+
+    <!-- Notification detail shown when work profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
+    <string name="profile_encrypted_detail">Work profile locked</string>
+    <!-- Notification message shown when work profile is credential encrypted and requires the user to unlock before some features are usable [CHAR LIMIT=30] -->
+    <string name="profile_encrypted_message">Tap to unlock work profile</string>
 
     <!-- Title of notification shown after a MTP device is connected to Android. -->
     <string name="usb_mtp_launch_notification_title">Connected to <xliff:g id="product_name">%1$s</xliff:g></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f75f023..2d3ad17 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1770,10 +1770,11 @@
   <java-symbol type="string" name="adb_active_notification_title" />
   <java-symbol type="string" name="share_remote_bugreport_notification_title" />
   <java-symbol type="string" name="share_remote_bugreport_notification_message" />
+  <java-symbol type="string" name="share_finished_remote_bugreport_notification_message" />
+  <java-symbol type="string" name="sharing_remote_bugreport_notification_title" />
+  <java-symbol type="string" name="sharing_remote_bugreport_notification_message" />
   <java-symbol type="string" name="share_remote_bugreport_notification_accept" />
   <java-symbol type="string" name="share_remote_bugreport_notification_decline" />
-  <java-symbol type="string" name="remote_bugreport_progress_notification_title" />
-  <java-symbol type="string" name="remote_bugreport_progress_notification_message_can_cancel" />
   <java-symbol type="string" name="aerr_application" />
   <java-symbol type="string" name="aerr_process" />
   <java-symbol type="string" name="aerr_application_repeated" />
@@ -2522,6 +2523,8 @@
   <java-symbol type="string" name="user_encrypted_title" />
   <java-symbol type="string" name="user_encrypted_message" />
   <java-symbol type="string" name="user_encrypted_detail" />
+  <java-symbol type="string" name="profile_encrypted_detail" />
+  <java-symbol type="string" name="profile_encrypted_message" />
   <java-symbol type="drawable" name="ic_user_secure" />
 
   <java-symbol type="string" name="usb_mtp_launch_notification_title" />
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index 605f067..9ab62cc 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -24,6 +24,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.NetworkScorerAppManager.NetworkScorerAppData;
+import android.os.UserHandle;
 import android.test.InstrumentationTestCase;
 import android.util.Pair;
 
@@ -116,14 +117,14 @@
             }
         }
 
-        Mockito.when(mMockPm.queryBroadcastReceivers(
+        Mockito.when(mMockPm.queryBroadcastReceiversAsUser(
                 Mockito.argThat(new ArgumentMatcher<Intent>() {
                     @Override
                     public boolean matches(Object object) {
                         Intent intent = (Intent) object;
                         return NetworkScoreManager.ACTION_SCORE_NETWORKS.equals(intent.getAction());
                     }
-                }), Mockito.eq(0)))
+                }), Mockito.eq(0), Mockito.eq(UserHandle.USER_SYSTEM)))
                 .thenReturn(receivers);
     }
 
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
new file mode 100644
index 0000000..d2e811c
--- /dev/null
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.method;
+
+import android.app.Activity;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.InputType;
+import android.text.method.BaseKeyListener;
+import android.text.method.KeyListenerTestCase;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.TextView.BufferType;
+
+/**
+ * Test backspace key handling of {@link android.text.method.BaseKeyListner}.
+ *
+ * TODO: Move some of test cases to the CTS.
+ */
+public class BackspaceTest extends KeyListenerTestCase {
+    private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
+        public int getInputType() {
+            return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+        }
+    };
+
+    // Sync the state to the TextView and call onKeyDown with KEYCODE_DEL key event.
+    // Then update the state to the result of TextView.
+    private void backspace(final EditorState state, int modifiers) {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText(state.mText, BufferType.EDITABLE);
+                mTextView.setKeyListener(mKeyListener);
+                mTextView.setSelection(state.mSelectionStart, state.mSelectionEnd);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        assertTrue(mTextView.hasWindowFocus());
+
+        final KeyEvent keyEvent = getKey(KeyEvent.KEYCODE_DEL, modifiers);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.onKeyDown(keyEvent.getKeyCode(), keyEvent);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        state.mText = mTextView.getText();
+        state.mSelectionStart = mTextView.getSelectionStart();
+        state.mSelectionEnd = mTextView.getSelectionEnd();
+    }
+
+    @SmallTest
+    public void testSurrogatePairs() {
+        EditorState state = new EditorState();
+
+        state.setByString("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F441 U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // TODO: introduce edge cases.
+    }
+
+    @SmallTest
+    public void testReplacementSpan() {
+        EditorState state = new EditorState();
+
+        // ReplacementSpan will be set to "()" region.
+        state.setByString("'abc' ( 'de' ) 'fg' |");
+        backspace(state, 0);
+        state.assertEquals("'abc' ( 'de' ) 'f' |");
+        backspace(state, 0);
+        state.assertEquals("'abc' ( 'de' ) |");
+        backspace(state, 0);
+        state.assertEquals("'abc' |");
+        backspace(state, 0);
+        state.assertEquals("'ab' |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'abc' [ ( 'de' ) ] 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'abc' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'ab' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("'a' | 'fg'");
+        backspace(state, 0);
+        state.assertEquals("| 'fg'");
+        backspace(state, 0);
+        state.assertEquals("| 'fg'");
+
+        state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'");
+        backspace(state, 0);
+        state.assertEquals("'ab' | 'g'");
+        backspace(state, 0);
+        state.assertEquals("'a' | 'g'");
+        backspace(state, 0);
+        state.assertEquals("| 'g'");
+        backspace(state, 0);
+        state.assertEquals("| 'g'");
+
+        // TODO: introduce edge cases.
+    }
+
+    @SmallTest
+    public void testCombiningEnclosingKeycaps() {
+        EditorState state = new EditorState();
+
+        // U+20E3 is COMBINING ENCLOSING KEYCAP.
+        state.setByString("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector before COMBINING ECLOSING KEYCAP
+        state.setByString("'1' U+FE0E U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'1' U+E0101 U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Edge cases
+        // multiple COMBINING ENCLOSING KEYCAP
+        state.setByString("'1' U+20E3 U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated COMBINING ENCLOSING KEYCAP
+        state.setByString("U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated multiple COMBINING ENCLOSING KEYCAP
+        state.setByString("U+20E3 U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testVariationSelector() {
+        EditorState state = new EditorState();
+
+        // U+FE0F is VARIATION SELECTOR-16.
+        state.setByString("'#' U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // U+E0100 is VARIATION SELECTOR-17.
+        state.setByString("U+845B U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Edge cases
+        // Isolated variation selector
+        state.setByString("U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated multiple variation selectors
+        state.setByString("U+FE0F U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+FE0F U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+E0100 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+E0100 U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Multiple variation selectors
+        state.setByString("'#' U+FE0F U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("'#' U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'#' U+FE0F U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("'#' U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+845B U+E0100 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("U+845B U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+845B U+E0100 U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("U+845B U+E0100 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testEmojiZWJSequence() {
+        EditorState state = new EditorState();
+
+        // U+200D is ZERO WIDTH JOINER.
+        state.setByString("U+1F441 U+200D U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F441 U+200D U+1F5E8 U+FE0E |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Edge cases
+        // End with ZERO WIDTH JOINER
+        state.setByString("U+1F441 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Start with ZERO WIDTH JOINER
+        state.setByString("U+200D U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+FE0E U+200D U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("U+FE0E U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+FE0E |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Multiple ZERO WIDTH JOINER
+        state.setByString("U+1F441 U+200D U+200D U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 U+200D U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated ZERO WIDTH JOINER
+        state.setByString("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated multiple ZERO WIDTH JOINER
+        state.setByString("U+200D U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testFlags() {
+        EditorState state = new EditorState();
+
+        // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U.
+        // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S.
+        state.setByString("U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'a' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("U+1F1FA U+1F1F8 U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        state.setByString("'a' U+1F1FA U+1F1F8 'b' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' U+1F1FA U+1F1F8 'b' |");
+        backspace(state, 0);
+        state.assertEquals("'a' U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("'a' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Edcae cases
+        // Isolated regional indicator symbol
+        state.setByString("U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Odd numbered regional indicator symbols
+        state.setByString("U+1F1FA U+1F1F8 U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA U+1F1F8 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testEmojiModifier() {
+        EditorState state = new EditorState();
+
+        // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
+        state.setByString("U+1F466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Edge cases
+        // Isolated emoji modifier
+        state.setByString("U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Isolated multiple emoji modifier
+        state.setByString("U+1F3FB U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Multiple emoji modifiers
+        state.setByString("U+1F466 U+1F3FB U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+
+    @SmallTest
+    public void testMixedEdgeCases() {
+        EditorState state = new EditorState();
+
+        // COMBINING ENCLOSING KEYCAP + variation selector
+        state.setByString("'1' U+20E3 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("'1' |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector + COMBINING ENCLOSING KEYCAP
+        state.setByString("U+2665 U+FE0F U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+2665 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // COMBINING ENCLOSING KEYCAP + ending with ZERO WIDTH JOINER
+        state.setByString("'1' U+20E3 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // COMBINING ENCLOSING KEYCAP + ZERO WIDTH JOINER
+        state.setByString("'1' U+20E3 U+200D U+1F5E8 |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Start with ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+        state.setByString("U+200D U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+        state.setByString("U+1F441 U+200D U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F441 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // COMBINING ENCLOSING KEYCAP + regional indicator symbol
+        state.setByString("'1' U+20E3 U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Regional indicator symbol + COMBINING ENCLOSING KEYCAP
+        state.setByString("U+1F1FA U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // COMBINING ENCLOSING KEYCAP + emoji modifier
+        state.setByString("'1' U+20E3 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("'1' U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Emoji modifier + COMBINING ENCLOSING KEYCAP
+        state.setByString("U+1F466 U+1F3FB U+20E3 |");
+        backspace(state, 0);
+        state.assertEquals("U+1f466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector + end with ZERO WIDTH JOINER
+        state.setByString("U+2665 U+FE0F U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+2665 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector + ZERO WIDTH JOINER
+        state.setByString("U+1F469 U+200D U+2764 U+FE0F U+200D U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Start with ZERO WIDTH JOINER + variation selector
+        state.setByString("U+200D U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // ZERO WIDTH JOINER + variation selector
+        state.setByString("U+1F469 U+200D U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector + regional indicator symbol
+        state.setByString("U+2665 U+FE0F U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("U+2665 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Regional indicator symbol + variation selector
+        state.setByString("U+1F1FA U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Variation selector + emoji modifier
+        state.setByString("U+2665 U+FE0F U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+2665 U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Emoji modifier + variation selector
+        state.setByString("U+1F466 U+1F3FB U+FE0F |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Start withj ZERO WIDTH JOINER + regional indicator symbol
+        state.setByString("U+200D U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // ZERO WIDTH JOINER + Regional indicator symbol
+        state.setByString("U+1F469 U+200D U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("U+1F469 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Regional indicator symbol + end with ZERO WIDTH JOINER
+        state.setByString("U+1F1FA U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Regional indicator symbol + ZERO WIDTH JOINER
+        state.setByString("U+1F1FA U+200D U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Start with ZERO WIDTH JOINER + emoji modifier
+        state.setByString("U+200D U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+200D |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // ZERO WIDTH JOINER + emoji modifier
+        state.setByString("U+1F469 U+200D U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+1F469 U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Emoji modifier + end with ZERO WIDTH JOINER
+        state.setByString("U+1F466 U+1F3FB U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Emoji modifier + ZERO WIDTH JOINER
+        state.setByString("U+1F466 U+1F3FB U+200D U+1F469 |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 U+1F3FB U+200D |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Regional indicator symbol + Emoji modifier
+        state.setByString("U+1F1FA U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("|");
+
+        // Emoji modifier + regional indicator symbol
+        state.setByString("U+1F466 U+1F3FB U+1F1FA |");
+        backspace(state, 0);
+        state.assertEquals("U+1F466 U+1F3FB |");
+        backspace(state, 0);
+        state.assertEquals("|");
+    }
+}
diff --git a/core/tests/coretests/src/android/text/method/EditorState.java b/core/tests/coretests/src/android/text/method/EditorState.java
new file mode 100644
index 0000000..bbbbd6d
--- /dev/null
+++ b/core/tests/coretests/src/android/text/method/EditorState.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.method;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.ReplacementSpan;
+
+import junit.framework.Assert;
+
+/**
+ * Represents an editor state.
+ *
+ * The editor state can be specified by following string format.
+ * - Components are separated by space(U+0020).
+ * - Single-quoted string for printable ASCII characters, e.g. 'a', '123'.
+ * - U+XXXX form can be used for a Unicode code point.
+ * - Components inside '[' and ']' are in selection.
+ * - Components inside '(' and ')' are in ReplacementSpan.
+ * - '|' is for specifying cursor position.
+ *
+ * Selection and cursor can not be specified at the same time.
+ *
+ * Example:
+ *   - "'Hello,' | U+0020 'world!'" means "Hello, world!" is displayed and the cursor position
+ *     is 6.
+ *   - "'abc' [ 'def' ] 'ghi'" means "abcdefghi" is displayed and "def" is selected.
+ *   - "U+1F441 | ( U+1F441 U+1F441 )" means three U+1F441 characters are displayed and
+ *     ReplacementSpan is set from offset 2 to 6.
+ */
+public class EditorState {
+    private static final String REPLACEMENT_SPAN_START = "(";
+    private static final String REPLACEMENT_SPAN_END = ")";
+    private static final String SELECTION_START = "[";
+    private static final String SELECTION_END = "]";
+    private static final String CURSOR = "|";
+
+    public Editable mText;
+    public int mSelectionStart = -1;
+    public int mSelectionEnd = -1;
+
+    public EditorState() {
+    }
+
+    /**
+     * A mocked {@link android.text.style.ReplacementSpan} for testing purpose.
+     */
+    private static class MockReplacementSpan extends ReplacementSpan {
+        public int getSize(Paint paint, CharSequence text, int start, int end,
+                Paint.FontMetricsInt fm) {
+            return 0;
+        }
+        public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
+                int y, int bottom, Paint paint) {
+        }
+    }
+
+    // Returns true if the code point is ASCII and graph.
+    private boolean isGraphicAscii(int codePoint) {
+        return 0x20 < codePoint && codePoint < 0x7F;
+    }
+
+    // Setup editor state with string. Please see class description for string format.
+    public void setByString(String string) {
+        final StringBuilder sb = new StringBuilder();
+        int replacementSpanStart = -1;
+        int replacementSpanEnd = -1;
+        mSelectionStart = -1;
+        mSelectionEnd = -1;
+
+        final String[] tokens = string.split(" +");
+        for (String token : tokens) {
+            if (token.startsWith("'") && token.endsWith("'")) {
+                for (int i = 1; i < token.length() - 1; ++i) {
+                    final char ch = token.charAt(1);
+                    if (!isGraphicAscii(ch)) {
+                        throw new IllegalArgumentException(
+                                "Only printable characters can be in single quote. " +
+                                "Use U+" + Integer.toHexString(ch).toUpperCase() + " instead");
+                    }
+                }
+                sb.append(token.substring(1, token.length() - 1));
+            } else if (token.startsWith("U+")) {
+                final int codePoint = Integer.parseInt(token.substring(2), 16);
+                if (codePoint < 0 || 0x10FFFF < codePoint) {
+                    throw new IllegalArgumentException("Invalid code point is specified:" + token);
+                }
+                sb.append(Character.toChars(codePoint));
+            } else if (token.equals(CURSOR)) {
+                if (mSelectionStart != -1 || mSelectionEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionStart = mSelectionEnd = sb.length();
+            } else if (token.equals(SELECTION_START)) {
+                if (mSelectionStart != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionStart = sb.length();
+            } else if (token.equals(SELECTION_END)) {
+                if (mSelectionEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Two or more cursor/selection positions are specified.");
+                }
+                mSelectionEnd = sb.length();
+            } else if (token.equals(REPLACEMENT_SPAN_START)) {
+                if (replacementSpanStart != -1) {
+                    throw new IllegalArgumentException(
+                            "Only one replacement span is supported");
+                }
+                replacementSpanStart = sb.length();
+            } else if (token.equals(REPLACEMENT_SPAN_END)) {
+                if (replacementSpanEnd != -1) {
+                    throw new IllegalArgumentException(
+                            "Only one replacement span is supported");
+                }
+                replacementSpanEnd = sb.length();
+            } else {
+                throw new IllegalArgumentException("Unknown or invalid token: " + token);
+            }
+        }
+
+        if (mSelectionStart == -1 || mSelectionEnd == -1) {
+              if (mSelectionEnd != -1) {
+                  throw new IllegalArgumentException(
+                          "Selection start position doesn't exist.");
+              } else if (mSelectionStart != -1) {
+                  throw new IllegalArgumentException(
+                          "Selection end position doesn't exist.");
+              } else {
+                  throw new IllegalArgumentException(
+                          "At least cursor position or selection range must be specified.");
+              }
+        } else if (mSelectionStart > mSelectionEnd) {
+              throw new IllegalArgumentException(
+                      "Selection start position appears after end position.");
+        }
+
+        final Spannable spannable = new SpannableString(sb.toString());
+
+        if (replacementSpanStart != -1 || replacementSpanEnd != -1) {
+            if (replacementSpanStart == -1) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan start position doesn't exist.");
+            }
+            if (replacementSpanEnd == -1) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan end position doesn't exist.");
+            }
+            if (replacementSpanStart > replacementSpanEnd) {
+                throw new IllegalArgumentException(
+                        "ReplacementSpan start position appears after end position.");
+            }
+            spannable.setSpan(new MockReplacementSpan(), replacementSpanStart, replacementSpanEnd,
+                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        }
+        mText = Editable.Factory.getInstance().newEditable(spannable);
+    }
+
+    public void assertEquals(String string) {
+        EditorState expected = new EditorState();
+        expected.setByString(string);
+
+        Assert.assertEquals(expected.mText.toString(), mText.toString());
+        Assert.assertEquals(expected.mSelectionStart, mSelectionStart);
+        Assert.assertEquals(expected.mSelectionEnd, mSelectionEnd);
+    }
+}
+
diff --git a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
new file mode 100644
index 0000000..4b4e7af
--- /dev/null
+++ b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.method;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.text.format.DateUtils;
+import android.view.KeyEvent;
+import android.widget.EditText;
+import android.widget.TextViewActivity;
+
+import com.android.frameworks.coretests.R;
+
+public abstract class KeyListenerTestCase extends
+        ActivityInstrumentationTestCase2<TextViewActivity> {
+
+    protected TextViewActivity mActivity;
+    protected Instrumentation mInstrumentation;
+    protected EditText mTextView;
+
+    public KeyListenerTestCase() {
+        super(TextViewActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mActivity = getActivity();
+        mInstrumentation = getInstrumentation();
+        mTextView = (EditText) mActivity.findViewById(R.id.textview);
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Ensure that the screen is on for this test.
+                mTextView.setKeepScreenOn(true);
+            }
+        });
+
+        assertTrue(mActivity.waitForWindowFocus(5 * DateUtils.SECOND_IN_MILLIS));
+    }
+
+    protected static KeyEvent getKey(int keycode, int metaState) {
+        long currentTime = System.currentTimeMillis();
+        return new KeyEvent(currentTime, currentTime, KeyEvent.ACTION_DOWN, keycode,
+                0 /* repeat */, metaState);
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/EditorCursorTest.java b/core/tests/coretests/src/android/widget/EditorCursorTest.java
new file mode 100644
index 0000000..04c8b8c
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/EditorCursorTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.ViewGroup;
+
+public class EditorCursorTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+
+    private EditText mEditText;
+    private final String RTL_STRING = "مرحبا الروبوت مرحبا الروبوت مرحبا الروبوت";
+
+    public EditorCursorTest() {
+        super(TextViewActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mEditText = new EditText(getActivity());
+        mEditText.setTextSize(30);
+        mEditText.setSingleLine(true);
+        mEditText.setLines(1);
+        mEditText.setPadding(15, 15, 15, 15);
+        ViewGroup.LayoutParams editTextLayoutParams = new ViewGroup.LayoutParams(200,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        mEditText.setLayoutParams(editTextLayoutParams);
+
+        final FrameLayout layout = new FrameLayout(getActivity());
+        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT,
+                ViewGroup.LayoutParams.MATCH_PARENT);
+        layout.setLayoutParams(layoutParams);
+        layout.addView(mEditText);
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getActivity().setContentView(layout);
+                mEditText.requestFocus();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+    }
+
+    @SmallTest
+    public void testCursorIsInViewBoundariesWhenOnRightForLtr() throws Exception {
+        // Asserts that when an EditText has LTR text, and cursor is at the end (right),
+        // cursor is drawn to the right edge of the view
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEditText.setText("aaaaaaaaaaaaaaaaaaaaaa");
+                int length = mEditText.getText().length();
+                mEditText.setSelection(length, length);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        Editor editor = mEditText.getEditorForTesting();
+        Drawable drawable = editor.getCursorDrawable()[0];
+        Rect drawableBounds = drawable.getBounds();
+        Rect drawablePadding = new Rect();
+        drawable.getPadding(drawablePadding);
+
+        // right edge of the view including the scroll
+        int maxRight = mEditText.getWidth() - mEditText.getCompoundPaddingRight()
+                - mEditText.getCompoundPaddingLeft() + +mEditText.getScrollX();
+        int diff = drawableBounds.right - drawablePadding.right - maxRight;
+        assertTrue(diff >= 0 && diff <= 1);
+    }
+
+    @SmallTest
+    public void testCursorIsInViewBoundariesWhenOnLeftForLtr() throws Exception {
+        // Asserts that when an EditText has LTR text, and cursor is at the beginning,
+        // cursor is drawn to the left edge of the view
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEditText.setText("aaaaaaaaaaaaaaaaaaaaaa");
+                mEditText.setSelection(0, 0);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        Drawable drawable = mEditText.getEditorForTesting().getCursorDrawable()[0];
+        Rect drawableBounds = drawable.getBounds();
+        Rect drawablePadding = new Rect();
+        drawable.getPadding(drawablePadding);
+
+        int diff = drawableBounds.left + drawablePadding.left;
+        assertTrue(diff >= 0 && diff <= 1);
+    }
+
+    @SmallTest
+    public void testCursorIsInViewBoundariesWhenOnRightForRtl() throws Exception {
+        // Asserts that when an EditText has RTL text, and cursor is at the end,
+        // cursor is drawn to the left edge of the view
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEditText.setText(RTL_STRING);
+                mEditText.setSelection(0, 0);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        Drawable drawable = mEditText.getEditorForTesting().getCursorDrawable()[0];
+        Rect drawableBounds = drawable.getBounds();
+        Rect drawablePadding = new Rect();
+        drawable.getPadding(drawablePadding);
+
+        int maxRight = mEditText.getWidth() - mEditText.getCompoundPaddingRight()
+                - mEditText.getCompoundPaddingLeft() + mEditText.getScrollX();
+
+        int diff = drawableBounds.right - drawablePadding.right - maxRight;
+        assertTrue(diff >= 0 && diff <= 1);
+    }
+
+    @SmallTest
+    public void testCursorIsInViewBoundariesWhenOnLeftForRtl() throws Exception {
+        // Asserts that when an EditText has RTL text, and cursor is at the beginning,
+        // cursor is drawn to the right edge of the view
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mEditText.setText(RTL_STRING);
+                int length = mEditText.getText().length();
+                mEditText.setSelection(length, length);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        Drawable drawable = mEditText.getEditorForTesting().getCursorDrawable()[0];
+        Rect drawableBounds = drawable.getBounds();
+        Rect drawablePadding = new Rect();
+        drawable.getPadding(drawablePadding);
+
+        int diff = drawableBounds.left - mEditText.getScrollX() + drawablePadding.left;
+        assertTrue(diff >= 0 && diff <= 1);
+    }
+
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewActivity.java b/core/tests/coretests/src/android/widget/TextViewActivity.java
index d4945ba..03358a8 100644
--- a/core/tests/coretests/src/android/widget/TextViewActivity.java
+++ b/core/tests/coretests/src/android/widget/TextViewActivity.java
@@ -20,15 +20,58 @@
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.os.SystemClock;
+import android.util.Log;
 
 /**
  * An activity for testing the TextView widget.
+ *
+ * This class is copied from {@link android.text.method.cts.KeyListenerCtsActivity} in
+ * CtsTextTestCase.  The original class is located at
+ * cts/tests/tests/text/src/android/text/method/cts/KeyListenerCtsActivity.java
  */
 public class TextViewActivity extends Activity {
+    private boolean mHasWindowFocus = false;
+    private Object mHasWindowFocusLock = new Object();
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_text_view);
     }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        if (!hasFocus) {
+            Log.w("TextViewActivity", "TextViewActivity lost window focus");
+        }
+        synchronized(mHasWindowFocusLock) {
+            mHasWindowFocus = hasFocus;
+            mHasWindowFocusLock.notify();
+        }
+    }
+
+    /**
+     * Blocks the calling thread until the {@link KeyListenerCtsActivity} has window focus or the
+     * specified duration (in milliseconds) has passed.
+     */
+    public boolean waitForWindowFocus(long durationMillis) {
+        long elapsedMillis = SystemClock.elapsedRealtime();
+        synchronized(mHasWindowFocusLock) {
+            mHasWindowFocus = hasWindowFocus();
+            while (!mHasWindowFocus && durationMillis > 0) {
+                long newElapsedMillis = SystemClock.elapsedRealtime();
+                durationMillis -= (newElapsedMillis - elapsedMillis);
+                elapsedMillis = newElapsedMillis;
+                if (durationMillis > 0) {
+                    try {
+                        mHasWindowFocusLock.wait(durationMillis);
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+            return mHasWindowFocus;
+        }
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index d133a12..f962a43 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -20,11 +20,13 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
 import android.os.Parcel;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.LocaleList;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
 import android.view.inputmethod.InputMethodSubtype;
@@ -217,7 +219,7 @@
         // Make sure that an automatic subtype (overridesImplicitlyEnabledSubtype:true) is
         // selected no matter what locale is specified.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);
             subtypes.add(nonAutoEnGB);
             subtypes.add(nonAutoJa);
@@ -230,7 +232,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_EN_US, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_US))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(autoSubtype, result.get(0));
         }
@@ -239,7 +244,7 @@
         // selected as long as there is no no automatic subtype
         // (overridesImplicitlyEnabledSubtype:true) in the given list.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);  // locale == "en_US"
             subtypes.add(nonAutoEnGB);
             subtypes.add(nonAutoJa);
@@ -251,8 +256,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_EN_US, imi);
-            assertEquals(1, result.size());
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_US))
+                                    .getResources(),
+                            imi);
             verifyEquality(nonAutoEnUS, result.get(0));
         }
 
@@ -260,7 +267,7 @@
         // selected as long as there is no automatic subtype
         // (overridesImplicitlyEnabledSubtype:true) in the given list.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);
             subtypes.add(nonAutoEnGB); // locale == "en_GB"
             subtypes.add(nonAutoJa);
@@ -271,7 +278,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_EN_GB, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_EN_GB))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoEnGB, result.get(0));
         }
@@ -281,7 +291,7 @@
         // try to find a subtype whose language is equal to the language part of the given locale.
         // Here make sure that a subtype (locale: "fr_CA") can be found with locale: "fr".
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoFrCA);  // locale == "fr_CA"
             subtypes.add(nonAutoJa);
             subtypes.add(nonAutoFil);
@@ -292,13 +302,16 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_FR, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_FR))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoFrCA, result.get(0));
         }
         // Then make sure that a subtype (locale: "fr") can be found with locale: "fr_CA".
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoFr);  // locale == "fr"
             subtypes.add(nonAutoJa);
             subtypes.add(nonAutoFil);
@@ -309,7 +322,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_FR_CA, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_FR_CA))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoFrCA, result.get(0));
         }
@@ -317,7 +333,7 @@
         // Make sure that subtypes which have "EnabledWhenDefaultIsNotAsciiCapable" in its
         // extra value is selected if and only if all other selected IMEs are not AsciiCapable.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);
             subtypes.add(nonAutoJa);    // not ASCII capable
             subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype);
@@ -327,7 +343,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_JA_JP, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_JA_JP))
+                                    .getResources(),
+                            imi);
             assertEquals(3, result.size());
             verifyEquality(nonAutoJa, result.get(0));
             verifyEquality(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype, result.get(1));
@@ -336,7 +355,7 @@
 
         // Make sure that 3-letter language code can be handled.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);
             subtypes.add(nonAutoFil);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -344,7 +363,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_FIL_PH, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_FIL_PH))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoFil, result.get(0));
         }
@@ -352,7 +374,7 @@
         // Make sure that we never end up matching "fi" (finnish) with "fil" (filipino).
         // Also make sure that the first subtype will be used as the last-resort candidate.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoJa);
             subtypes.add(nonAutoEnUS);
             subtypes.add(nonAutoFil);
@@ -361,14 +383,17 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_FI, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_FI))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoJa, result.get(0));
         }
 
         // Make sure that "in" and "id" conversion is taken into account.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoIn);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -376,12 +401,15 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_IN, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_IN))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoIn, result.get(0));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoIn);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -389,12 +417,15 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_ID, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_ID))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoIn, result.get(0));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoId);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -402,12 +433,15 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_IN, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_IN))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoId, result.get(0));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoId);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -415,7 +449,10 @@
                     "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT,
                     subtypes);
             final ArrayList<InputMethodSubtype> result =
-                    callGetImplicitlyApplicableSubtypesLockedWithLocale(LOCALE_ID, imi);
+                    InputMethodUtils.getImplicitlyApplicableSubtypesLocked(
+                            createTargetContextWithLocales(new LocaleList(LOCALE_ID))
+                                    .getResources(),
+                            imi);
             assertEquals(1, result.size());
             verifyEquality(nonAutoId, result.get(0));
         }
@@ -445,7 +482,7 @@
         final boolean CHECK_COUNTRY = true;
 
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
                     "com.android.apps.inputmethod.latin",
@@ -477,7 +514,7 @@
 
         // Make sure that 3-letter language code ("fil") can be handled.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoFil);
             final InputMethodInfo imi = createDummyInputMethodInfo(
                     "com.android.apps.inputmethod.latin",
@@ -504,7 +541,7 @@
 
         // Make sure that 3-letter language code ("fil_PH") can be handled.
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoFilPH);
             final InputMethodInfo imi = createDummyInputMethodInfo(
                     "com.android.apps.inputmethod.latin",
@@ -531,7 +568,7 @@
 
         // Make sure that a subtype whose locale is "in" can be queried with "id".
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoIn);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -550,7 +587,7 @@
 
         // Make sure that a subtype whose locale is "id" can be queried with "in".
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(nonAutoId);
             subtypes.add(nonAutoEnUS);
             final InputMethodInfo imi = createDummyInputMethodInfo(
@@ -568,24 +605,11 @@
         }
     }
 
-    private ArrayList<InputMethodSubtype> callGetImplicitlyApplicableSubtypesLockedWithLocale(
-            final Locale locale, final InputMethodInfo imi) {
-        final Context context = getInstrumentation().getTargetContext();
-        final Locale initialLocale = context.getResources().getConfiguration().locale;
-        try {
-            context.getResources().getConfiguration().setLocale(locale);
-            return InputMethodUtils.getImplicitlyApplicableSubtypesLocked(context.getResources(),
-                    imi);
-        } finally {
-            context.getResources().getConfiguration().setLocale(initialLocale);
-        }
-    }
-
     private void assertDefaultEnabledImes(final ArrayList<InputMethodInfo> preinstalledImes,
             final Locale systemLocale, final boolean isSystemReady, String... expectedImeNames) {
-        final Context context = getInstrumentation().getTargetContext();
-        final String[] actualImeNames = getPackageNames(callGetDefaultEnabledImesWithLocale(
-                context, isSystemReady, preinstalledImes, systemLocale));
+        final Context context = createTargetContextWithLocales(new LocaleList(systemLocale));
+        final String[] actualImeNames = getPackageNames(
+                InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, preinstalledImes));
         assertEquals(expectedImeNames.length, actualImeNames.length);
         for (int i = 0; i < expectedImeNames.length; ++i) {
             assertEquals(expectedImeNames[i], actualImeNames[i]);
@@ -606,16 +630,12 @@
         }
     }
 
-    private static ArrayList<InputMethodInfo> callGetDefaultEnabledImesWithLocale(
-            final Context context, final boolean isSystemReady,
-            final ArrayList<InputMethodInfo> imis, final Locale locale) {
-        final Locale initialLocale = context.getResources().getConfiguration().locale;
-        try {
-            context.getResources().getConfiguration().setLocale(locale);
-            return InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, imis);
-        } finally {
-            context.getResources().getConfiguration().setLocale(initialLocale);
-        }
+    private Context createTargetContextWithLocales(final LocaleList locales) {
+        final Configuration resourceConfiguration = new Configuration();
+        resourceConfiguration.setLocales(locales);
+        return getInstrumentation()
+                .getTargetContext()
+                .createConfigurationContext(resourceConfiguration);
     }
 
     private String[] getPackageNames(final ArrayList<InputMethodInfo> imis) {
@@ -692,7 +712,7 @@
     private static ArrayList<InputMethodInfo> getImesWithDefaultVoiceIme() {
         ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
                     IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -709,7 +729,7 @@
     private static ArrayList<InputMethodInfo> getImesWithoutDefaultVoiceIme() {
         ArrayList<InputMethodInfo> preinstalledImes = new ArrayList<>();
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
                     IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -720,7 +740,7 @@
                     "dummy.voice1", "DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("auto", SUBTYPE_MODE_VOICE, IS_AUX,
                     IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -731,7 +751,7 @@
                     "dummy.voice2", "DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_VOICE, IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -739,7 +759,7 @@
                     "dummy.voice3", "DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes));
         }
         {
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -767,7 +787,7 @@
         // a dummy Voice IME
         {
             final boolean isDefaultIme = false;
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("", SUBTYPE_MODE_VOICE, IS_AUX,
                     IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -778,7 +798,7 @@
         // a dummy Hindi IME
         {
             final boolean isDefaultIme = contains(new String[]{ "hi", "en-rIN" }, localeString);
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             // TODO: This subtype should be marked as IS_ASCII_CAPABLE
             subtypes.add(createDummyInputMethodSubtype("en_IN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
@@ -794,7 +814,7 @@
         // a dummy Pinyin IME
         {
             final boolean isDefaultIme = contains(new String[]{ "zh-rCN" }, localeString);
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("zh_CN", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -806,7 +826,7 @@
         // a dummy Korean IME
         {
             final boolean isDefaultIme = contains(new String[]{ "ko" }, localeString);
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("ko", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -819,7 +839,7 @@
         {
             final boolean isDefaultIme = contains(
                     new String[]{ "en-rUS", "en-rGB", "en-rIN", "en", "hi" }, localeString);
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("en_US", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
@@ -840,7 +860,7 @@
         // a dummy Japanese IME
         {
             final boolean isDefaultIme = contains(new String[]{ "ja", "ja-rJP" }, localeString);
-            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+            final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
             subtypes.add(createDummyInputMethodSubtype("ja", SUBTYPE_MODE_KEYBOARD, !IS_AUX,
                     !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE,
                     !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE));
diff --git a/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java b/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java
index 49ae104..4845c4e 100644
--- a/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/LineBreakBufferedWriterTest.java
@@ -180,6 +180,22 @@
         assertOutput("aaaaaaaaaabbbbbc\nd", "ddddddddd");
     }
 
+    public void testMoreThenInitialCapacitySimpleWrites() {
+        // This check is different from testMoreThanBufferSizeChar. The initial capacity is lower
+        // than the maximum buffer size here.
+        final LineBreakBufferedWriter lw = new LineBreakBufferedWriter(mWriter, 1024, 3);
+
+        for(int i = 0; i < 10; i++) {
+            lw.print('$');
+        }
+        for(int i = 0; i < 10; i++) {
+            lw.print('%');
+        }
+        lw.flush();
+
+        assertOutput("$$$$$$$$$$%%%%%%%%%%");
+    }
+
     private void assertOutput(String... golden) {
         List<String> goldList = createTestGolden(golden);
         assertEquals(goldList, mWriter.getStrings());
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
index edeecb2..26f768b 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/Android.mk
@@ -29,6 +29,8 @@
 
 LOCAL_DEX_PREOPT := false
 
+LOCAL_JAVACFLAGS := -nowarn
+
 mainDexList:= \
     $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
 
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/Test.java b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/Test.java
index 5e931bc..8d065a4 100644
--- a/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/Test.java
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyAndException/src/com/android/multidexlegacyandexception/Test.java
@@ -15,14 +15,13 @@
  */
 package com.android.multidexlegacyandexception;
 
-import android.test.ActivityInstrumentationTestCase2;
-
 /**
  * Run the tests with: <code>adb shell am instrument -w
  com.android.multidexlegacyandexception/android.test.InstrumentationTestRunner
 </code>
  */
-public class Test extends ActivityInstrumentationTestCase2<MainActivity> {
+@SuppressWarnings("deprecation")
+public class Test extends android.test.ActivityInstrumentationTestCase2<MainActivity> {
     public Test() {
         super(MainActivity.class);
     }
diff --git a/core/tests/systemproperties/Android.mk b/core/tests/systemproperties/Android.mk
index 9f01a28..0c20876 100644
--- a/core/tests/systemproperties/Android.mk
+++ b/core/tests/systemproperties/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_PACKAGE_NAME := FrameworksCoreSystemPropertiesTests
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 
 LOCAL_CERTIFICATE := platform
 
diff --git a/docs/html/guide/components/services.jd b/docs/html/guide/components/services.jd
index 8da1694..4053769 100644
--- a/docs/html/guide/components/services.jd
+++ b/docs/html/guide/components/services.jd
@@ -336,14 +336,11 @@
   protected void onHandleIntent(Intent intent) {
       // Normally we would do some work here, like download a file.
       // For our sample, we just sleep for 5 seconds.
-      long endTime = System.currentTimeMillis() + 5*1000;
-      while (System.currentTimeMillis() &lt; endTime) {
-          synchronized (this) {
-              try {
-                  wait(endTime - System.currentTimeMillis());
-              } catch (Exception e) {
-              }
-          }
+      try {
+          Thread.sleep(5000);
+      } catch (InterruptedException e) {
+          // Restore interrupt status.
+          Thread.currentThread().interrupt();
       }
   }
 }
@@ -405,14 +402,11 @@
       public void handleMessage(Message msg) {
           // Normally we would do some work here, like download a file.
           // For our sample, we just sleep for 5 seconds.
-          long endTime = System.currentTimeMillis() + 5*1000;
-          while (System.currentTimeMillis() &lt; endTime) {
-              synchronized (this) {
-                  try {
-                      wait(endTime - System.currentTimeMillis());
-                  } catch (Exception e) {
-                  }
-              }
+          try {
+              Thread.sleep(5000);
+          } catch (InterruptedException e) {
+              // Restore interrupt status.
+              Thread.currentThread().interrupt();
           }
           // Stop the service using the startId, so that we don't stop
           // the service in the middle of handling another job
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index 6309ed3..f741e3c 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -18,6 +18,9 @@
 
 import android.content.res.AssetManager;
 
+import java.nio.ByteBuffer;
+import java.util.List;
+
 /**
  * A family of typefaces with different styles.
  *
@@ -62,8 +65,9 @@
         return nAddFont(mNativePtr, path, ttcIndex);
     }
 
-    public boolean addFontWeightStyle(String path, int ttcIndex, int weight, boolean style) {
-        return nAddFontWeightStyle(mNativePtr, path, ttcIndex, weight, style);
+    public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontListParser.Axis> axes,
+            int weight, boolean style) {
+        return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style);
     }
 
     public boolean addFontFromAsset(AssetManager mgr, String path) {
@@ -73,8 +77,9 @@
     private static native long nCreateFamily(String lang, int variant);
     private static native void nUnrefFamily(long nativePtr);
     private static native boolean nAddFont(long nativeFamily, String path, int ttcIndex);
-    private static native boolean nAddFontWeightStyle(long nativeFamily, String path,
-            int ttcIndex, int weight, boolean isItalic);
+    private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font,
+            int ttcIndex, List<FontListParser.Axis> listOfAxis,
+            int weight, boolean isItalic);
     private static native boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr,
             String path);
 }
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 774f6b8..8f7c6a62 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -25,6 +25,7 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * Parser for font config files.
@@ -42,15 +43,26 @@
         public List<Alias> aliases;
     }
 
+    public static class Axis {
+        Axis(int tag, float styleValue) {
+            this.tag = tag;
+            this.styleValue = styleValue;
+        }
+        public final int tag;
+        public final float styleValue;
+    }
+
     public static class Font {
-        Font(String fontName, int ttcIndex, int weight, boolean isItalic) {
+        Font(String fontName, int ttcIndex, List<Axis> axes, int weight, boolean isItalic) {
             this.fontName = fontName;
             this.ttcIndex = ttcIndex;
+            this.axes = axes;
             this.weight = weight;
             this.isItalic = isItalic;
         }
         public String fontName;
         public int ttcIndex;
+        public final List<Axis> axes;
         public int weight;
         public boolean isItalic;
     }
@@ -93,9 +105,10 @@
         parser.require(XmlPullParser.START_TAG, null, "familyset");
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
-            if (parser.getName().equals("family")) {
+            String tag = parser.getName();
+            if (tag.equals("family")) {
                 config.families.add(readFamily(parser));
-            } else if (parser.getName().equals("alias")) {
+            } else if (tag.equals("alias")) {
                 config.aliases.add(readAlias(parser));
             } else {
                 skip(parser);
@@ -114,14 +127,7 @@
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
             if (tag.equals("font")) {
-                String ttcIndexStr = parser.getAttributeValue(null, "index");
-                int ttcIndex = ttcIndexStr == null ? 0 : Integer.parseInt(ttcIndexStr);
-                String weightStr = parser.getAttributeValue(null, "weight");
-                int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
-                boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
-                String filename = parser.nextText();
-                String fullFilename = "/system/fonts/" + filename;
-                fonts.add(new Font(fullFilename, ttcIndex, weight, isItalic));
+                fonts.add(readFont(parser));
             } else {
                 skip(parser);
             }
@@ -129,6 +135,70 @@
         return new Family(name, fonts, lang, variant);
     }
 
+    /** Matches leading and trailing XML whitespace. */
+    private static final Pattern FILENAME_WHITESPACE_PATTERN =
+            Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
+
+    private static Font readFont(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        String indexStr = parser.getAttributeValue(null, "index");
+        int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
+        List<Axis> axes = new ArrayList<Axis>();
+        String weightStr = parser.getAttributeValue(null, "weight");
+        int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
+        boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
+        StringBuilder filename = new StringBuilder();
+        while (parser.next() != XmlPullParser.END_TAG) {
+            if (parser.getEventType() == XmlPullParser.TEXT) {
+                filename.append(parser.getText());
+            }
+            if (parser.getEventType() != XmlPullParser.START_TAG) continue;
+            String tag = parser.getName();
+            if (tag.equals("axis")) {
+                axes.add(readAxis(parser));
+            } else {
+                skip(parser);
+            }
+        }
+        String fullFilename = "/system/fonts/" +
+                FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
+        return new Font(fullFilename, index, axes, weight, isItalic);
+    }
+
+    /** The 'tag' attribute value is read as four character values between 0 and 255 inclusive. */
+    private static final Pattern TAG_PATTERN = Pattern.compile("[\\x00-\\xFF]{4}");
+
+    /** The 'styleValue' attribute has an optional leading '-', followed by '<digits>',
+     *  '<digits>.<digits>', or '.<digits>' where '<digits>' is one or more of [0-9].
+     */
+    private static final Pattern STYLE_VALUE_PATTERN =
+            Pattern.compile("-?(([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))");
+
+    private static Axis readAxis(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int tag = 0;
+        String tagStr = parser.getAttributeValue(null, "tag");
+        if (tagStr != null && TAG_PATTERN.matcher(tagStr).matches()) {
+            tag = tagStr.charAt(0) << 24 +
+                  tagStr.charAt(1) << 16 +
+                  tagStr.charAt(2) <<  8 +
+                  tagStr.charAt(3);
+        } else {
+            throw new XmlPullParserException("Invalid tag attribute value.", parser, null);
+        }
+
+        float styleValue = 0;
+        String styleValueStr = parser.getAttributeValue(null, "stylevalue");
+        if (styleValueStr != null && STYLE_VALUE_PATTERN.matcher(styleValueStr).matches()) {
+            styleValue = Float.parseFloat(styleValueStr);
+        } else {
+            throw new XmlPullParserException("Invalid styleValue attribute value.", parser, null);
+        }
+
+        skip(parser);  // axis tag is empty, ignore any contents and consume end tag
+        return new Axis(tag, styleValue);
+    }
+
     private static Alias readAlias(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         Alias alias = new Alias();
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 1294323..f15aff7 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -17,7 +17,6 @@
 package android.graphics;
 
 import android.content.res.AssetManager;
-import android.graphics.FontListParser.Family;
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.SparseArray;
@@ -28,6 +27,8 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -259,10 +260,26 @@
         mStyle = nativeGetStyle(ni);
     }
 
-    private static FontFamily makeFamilyFromParsed(FontListParser.Family family) {
+    private static FontFamily makeFamilyFromParsed(FontListParser.Family family,
+            Map<String, ByteBuffer> bufferForPath) {
         FontFamily fontFamily = new FontFamily(family.lang, family.variant);
         for (FontListParser.Font font : family.fonts) {
-            fontFamily.addFontWeightStyle(font.fontName, font.ttcIndex, font.weight, font.isItalic);
+            ByteBuffer fontBuffer = bufferForPath.get(font.fontName);
+            if (fontBuffer == null) {
+                try (FileInputStream file = new FileInputStream(font.fontName)) {
+                    FileChannel fileChannel = file.getChannel();
+                    long fontSize = fileChannel.size();
+                    fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
+                    bufferForPath.put(font.fontName, fontBuffer);
+                } catch (IOException e) {
+                    Log.e(TAG, "Error mapping font file " + font.fontName);
+                    continue;
+                }
+            }
+            if (!fontFamily.addFontWeightStyle(fontBuffer, font.ttcIndex, font.axes,
+                    font.weight, font.isItalic)) {
+                Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex);
+            }
         }
         return fontFamily;
     }
@@ -280,13 +297,15 @@
             FileInputStream fontsIn = new FileInputStream(configFilename);
             FontListParser.Config fontConfig = FontListParser.parse(fontsIn);
 
+            Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
+
             List<FontFamily> familyList = new ArrayList<FontFamily>();
             // Note that the default typeface is always present in the fallback list;
             // this is an enhancement from pre-Minikin behavior.
             for (int i = 0; i < fontConfig.families.size(); i++) {
-                Family f = fontConfig.families.get(i);
+                FontListParser.Family f = fontConfig.families.get(i);
                 if (i == 0 || f.name == null) {
-                    familyList.add(makeFamilyFromParsed(f));
+                    familyList.add(makeFamilyFromParsed(f, bufferForPath));
                 }
             }
             sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
@@ -295,14 +314,14 @@
             Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
             for (int i = 0; i < fontConfig.families.size(); i++) {
                 Typeface typeface;
-                Family f = fontConfig.families.get(i);
+                FontListParser.Family f = fontConfig.families.get(i);
                 if (f.name != null) {
                     if (i == 0) {
                         // The first entry is the default typeface; no sense in
                         // duplicating the corresponding FontFamily.
                         typeface = sDefaultTypeface;
                     } else {
-                        FontFamily fontFamily = makeFamilyFromParsed(f);
+                        FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
                         FontFamily[] families = { fontFamily };
                         typeface = Typeface.createFromFamiliesWithDefault(families);
                     }
@@ -324,11 +343,11 @@
             Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e);
             // TODO: normal in non-Minikin case, remove or make error when Minikin-only
         } catch (FileNotFoundException e) {
-            Log.e(TAG, "Error opening " + configFilename);
+            Log.e(TAG, "Error opening " + configFilename, e);
         } catch (IOException e) {
-            Log.e(TAG, "Error reading " + configFilename);
+            Log.e(TAG, "Error reading " + configFilename, e);
         } catch (XmlPullParserException e) {
-            Log.e(TAG, "XML parse exception for " + configFilename);
+            Log.e(TAG, "XML parse exception for " + configFilename, e);
         }
     }
 
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index af8ccf5..77748a8 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -238,9 +238,6 @@
             mAnimatorSet.recordLastSeenTarget((DisplayListCanvas) canvas);
         }
         mAnimatedVectorState.mVectorDrawable.draw(canvas);
-        if (isStarted()) {
-            invalidateSelf();
-        }
     }
 
     @Override
@@ -611,10 +608,6 @@
         return mAnimatorSet.isRunning();
     }
 
-    private boolean isStarted() {
-        return mAnimatorSet.isStarted();
-    }
-
     /**
      * Resets the AnimatedVectorDrawable to the start state as specified in the animators.
      */
@@ -626,12 +619,6 @@
     @Override
     public void start() {
         ensureAnimatorSet();
-
-        // If any one of the animator has not ended, do nothing.
-        if (isStarted()) {
-            return;
-        }
-
         mAnimatorSet.start();
         invalidateSelf();
     }
@@ -652,6 +639,7 @@
     @Override
     public void stop() {
         mAnimatorSet.end();
+        invalidateSelf();
     }
 
     /**
@@ -774,6 +762,9 @@
      * @hide
      */
     public static class VectorDrawableAnimator {
+        private static final int NONE = 0;
+        private static final int START_ANIMATION = 1;
+        private static final int REVERSE_ANIMATION = 2;
         private AnimatorListener mListener = null;
         private final LongArray mStartDelays = new LongArray();
         private PropertyValuesHolder.PropertyValues mTmpValues =
@@ -782,15 +773,14 @@
         private boolean mContainsSequentialAnimators = false;
         private boolean mStarted = false;
         private boolean mInitialized = false;
-        private boolean mAnimationPending = false;
         private boolean mIsReversible = false;
         // This needs to be set before parsing starts.
         private boolean mShouldIgnoreInvalidAnim;
         // TODO: Consider using NativeAllocationRegistery to track native allocation
         private final VirtualRefBasePtr mSetRefBasePtr;
-        private WeakReference<RenderNode> mTarget = null;
         private WeakReference<RenderNode> mLastSeenTarget = null;
-
+        private int mLastListenerId = 0;
+        private int mPendingAnimationAction = NONE;
 
         VectorDrawableAnimator() {
             mSetPtr = nCreateAnimatorSet();
@@ -810,6 +800,7 @@
             mInitialized = true;
 
             // Check reversible.
+            mIsReversible = true;
             if (mContainsSequentialAnimators) {
                 mIsReversible = false;
             } else {
@@ -821,7 +812,6 @@
                     }
                 }
             }
-            mIsReversible = true;
         }
 
         private void parseAnimatorSet(AnimatorSet set, long startTime) {
@@ -1042,36 +1032,28 @@
          * to the last seen RenderNode target and start right away.
          */
         protected void recordLastSeenTarget(DisplayListCanvas canvas) {
-            if (mAnimationPending) {
-                mLastSeenTarget = new WeakReference<RenderNode>(
-                        RenderNodeAnimatorSetHelper.getTarget(canvas));
+            mLastSeenTarget = new WeakReference<RenderNode>(
+                    RenderNodeAnimatorSetHelper.getTarget(canvas));
+            if (mPendingAnimationAction != NONE) {
                 if (DBG_ANIMATION_VECTOR_DRAWABLE) {
                     Log.d(LOGTAG, "Target is set in the next frame");
                 }
-                mAnimationPending = false;
-                start();
-            } else {
-                mLastSeenTarget = new WeakReference<RenderNode>(
-                        RenderNodeAnimatorSetHelper.getTarget(canvas));
+                if (mPendingAnimationAction == START_ANIMATION) {
+                    start();
+                } else if (mPendingAnimationAction == REVERSE_ANIMATION) {
+                    reverse();
+                }
+                mPendingAnimationAction = NONE;
             }
-
-        }
-
-        private boolean setTarget(RenderNode node) {
-            if (mTarget != null && mTarget.get() != null) {
-                // TODO: Maybe we want to support target change.
-                throw new IllegalStateException("Target already set!");
-            }
-
-            node.addAnimator(this);
-            mTarget = new WeakReference<RenderNode>(node);
-            return true;
         }
 
         private boolean useLastSeenTarget() {
-            if (mLastSeenTarget != null && mLastSeenTarget.get() != null) {
-                setTarget(mLastSeenTarget.get());
-                return true;
+            if (mLastSeenTarget != null) {
+                final RenderNode target = mLastSeenTarget.get();
+                if (target != null && target.isAttached()) {
+                    target.addAnimator(this);
+                    return true;
+                }
             }
             return false;
         }
@@ -1081,12 +1063,8 @@
                 return;
             }
 
-            if (mStarted) {
-                return;
-            }
-
             if (!useLastSeenTarget()) {
-                mAnimationPending = true;
+                mPendingAnimationAction = START_ANIMATION;
                 return;
             }
 
@@ -1094,38 +1072,45 @@
                 Log.d(LOGTAG, "Target is set. Starting VDAnimatorSet from java");
             }
 
-           nStart(mSetPtr, this);
+            mStarted = true;
+            nStart(mSetPtr, this, ++mLastListenerId);
             if (mListener != null) {
                 mListener.onAnimationStart(null);
             }
-            mStarted = true;
         }
 
         public void end() {
-            if (mInitialized && mStarted) {
+            if (mInitialized && useLastSeenTarget()) {
+                // If no target has ever been set, no-op
                 nEnd(mSetPtr);
-                onAnimationEnd();
             }
         }
 
-        void reset() {
-            if (!mInitialized) {
-                return;
+        public void reset() {
+            if (mInitialized && useLastSeenTarget()) {
+                // If no target has ever been set, no-op
+                nReset(mSetPtr);
             }
-            // TODO: Need to implement reset.
-            Log.w(LOGTAG, "Reset is yet to be implemented");
-            nReset(mSetPtr);
         }
 
         // Current (imperfect) Java AnimatorSet cannot be reversed when the set contains sequential
         // animators or when the animator set has a start delay
         void reverse() {
-            if (!mIsReversible) {
+            if (!mIsReversible || !mInitialized) {
                 return;
             }
-            // TODO: Need to support reverse (non-public API)
-            Log.w(LOGTAG, "Reverse is yet to be implemented");
-            nReverse(mSetPtr, this);
+            if (!useLastSeenTarget()) {
+                mPendingAnimationAction = REVERSE_ANIMATION;
+                return;
+            }
+            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+                Log.d(LOGTAG, "Target is set. Reversing VDAnimatorSet from java");
+            }
+            mStarted = true;
+            nReverse(mSetPtr, this, ++mLastListenerId);
+            if (mListener != null) {
+                mListener.onAnimationStart(null);
+            }
         }
 
         public long getAnimatorNativePtr() {
@@ -1155,20 +1140,22 @@
             mListener = null;
         }
 
-        private void onAnimationEnd() {
+        private void onAnimationEnd(int listenerId) {
+            if (listenerId != mLastListenerId) {
+                return;
+            }
+            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
+                Log.d(LOGTAG, "on finished called from native");
+            }
             mStarted = false;
             if (mListener != null) {
                 mListener.onAnimationEnd(null);
             }
-            mTarget = null;
         }
 
         // onFinished: should be called from native
-        private static void callOnFinished(VectorDrawableAnimator set) {
-            if (DBG_ANIMATION_VECTOR_DRAWABLE) {
-                Log.d(LOGTAG, "on finished called from native");
-            }
-            set.onAnimationEnd();
+        private static void callOnFinished(VectorDrawableAnimator set, int id) {
+            set.onAnimationEnd(id);
         }
     }
 
@@ -1188,8 +1175,8 @@
     private static native long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
             float endValue);
     private static native void nSetPropertyHolderData(long nativePtr, float[] data, int length);
-    private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set);
-    private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set);
+    private static native void nStart(long animatorSetPtr, VectorDrawableAnimator set, int id);
+    private static native void nReverse(long animatorSetPtr, VectorDrawableAnimator set, int id);
     private static native void nEnd(long animatorSetPtr);
     private static native void nReset(long animatorSetPtr);
 }
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index daf2581..bffbc75 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -641,16 +641,22 @@
 
     @Override
     public void setTintList(ColorStateList tint) {
-        mBitmapState.mTint = tint;
-        mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
-        invalidateSelf();
+        final BitmapState state = mBitmapState;
+        if (state.mTint != tint) {
+            state.mTint = tint;
+            mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
+            invalidateSelf();
+        }
     }
 
     @Override
     public void setTintMode(PorterDuff.Mode tintMode) {
-        mBitmapState.mTintMode = tintMode;
-        mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
-        invalidateSelf();
+        final BitmapState state = mBitmapState;
+        if (state.mTintMode != tintMode) {
+            state.mTintMode = tintMode;
+            mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
+            invalidateSelf();
+        }
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 9c691e5..ee0861a 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -251,6 +251,7 @@
         boolean enabled = false;
         boolean pressed = false;
         boolean focused = false;
+        boolean hovered = false;
 
         for (int state : stateSet) {
             if (state == R.attr.state_enabled) {
@@ -259,11 +260,13 @@
                 focused = true;
             } else if (state == R.attr.state_pressed) {
                 pressed = true;
+            } else if (state == R.attr.state_hovered) {
+                hovered = true;
             }
         }
 
         setRippleActive(enabled && pressed);
-        setBackgroundActive(focused || (enabled && pressed), focused);
+        setBackgroundActive(hovered || focused || (enabled && pressed), focused || hovered);
 
         return changed;
     }
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index bdbf3c0..9e0f1b4 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -1482,8 +1482,9 @@
             if (mThemeAttrs != null) {
                 return true;
             }
-            boolean fillCanApplyTheme = canGradientApplyTheme(mFillColors);
-            boolean strokeCanApplyTheme = canGradientApplyTheme(mStrokeColors);
+
+            boolean fillCanApplyTheme = canComplexColorApplyTheme(mFillColors);
+            boolean strokeCanApplyTheme = canComplexColorApplyTheme(mStrokeColors);
             if (fillCanApplyTheme || strokeCanApplyTheme) {
                 return true;
             }
@@ -1493,30 +1494,42 @@
 
         @Override
         public void applyTheme(Theme t) {
+            // Resolve the theme attributes directly referred by the VectorDrawable.
             if (mThemeAttrs != null) {
                 final TypedArray a = t.resolveAttributes(mThemeAttrs, R.styleable.VectorDrawablePath);
                 updateStateFromTypedArray(a);
                 a.recycle();
             }
 
-            boolean fillCanApplyTheme = canGradientApplyTheme(mFillColors);
-            boolean strokeCanApplyTheme = canGradientApplyTheme(mStrokeColors);
+            // Resolve the theme attributes in-directly referred by the VectorDrawable, for example,
+            // fillColor can refer to a color state list which itself needs to apply theme.
+            // And this is the reason we still want to keep partial update for the path's properties.
+            boolean fillCanApplyTheme = canComplexColorApplyTheme(mFillColors);
+            boolean strokeCanApplyTheme = canComplexColorApplyTheme(mStrokeColors);
+
             if (fillCanApplyTheme) {
                 mFillColors = mFillColors.obtainForTheme(t);
-                nUpdateFullPathFillGradient(mNativePtr,
-                        ((GradientColor)mFillColors).getShader().getNativeInstance());
+                if (mFillColors instanceof GradientColor) {
+                    nUpdateFullPathFillGradient(mNativePtr,
+                            ((GradientColor) mFillColors).getShader().getNativeInstance());
+                } else if (mFillColors instanceof ColorStateList) {
+                    nSetFillColor(mNativePtr, mFillColors.getDefaultColor());
+                }
             }
 
             if (strokeCanApplyTheme) {
                 mStrokeColors = mStrokeColors.obtainForTheme(t);
-                nUpdateFullPathStrokeGradient(mNativePtr,
-                        ((GradientColor)mStrokeColors).getShader().getNativeInstance());
+                if (mStrokeColors instanceof GradientColor) {
+                    nUpdateFullPathStrokeGradient(mNativePtr,
+                            ((GradientColor) mStrokeColors).getShader().getNativeInstance());
+                } else if (mStrokeColors instanceof ColorStateList) {
+                    nSetStrokeColor(mNativePtr, mStrokeColors.getDefaultColor());
+                }
             }
         }
 
-        private boolean canGradientApplyTheme(ComplexColor complexColor) {
-            return complexColor != null && complexColor.canApplyTheme()
-                    && complexColor instanceof GradientColor;
+        private boolean canComplexColorApplyTheme(ComplexColor complexColor) {
+            return complexColor != null && complexColor.canApplyTheme();
         }
 
         /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index c8333c8..302b0bd 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -20,9 +20,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
+
 import com.android.org.bouncycastle.util.io.pem.PemObject;
 import com.android.org.bouncycastle.util.io.pem.PemReader;
 import com.android.org.bouncycastle.util.io.pem.PemWriter;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -147,20 +149,23 @@
         Reader reader = new InputStreamReader(bai, StandardCharsets.US_ASCII);
         PemReader pr = new PemReader(reader);
 
-        CertificateFactory cf = CertificateFactory.getInstance("X509");
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X509");
 
-        List<X509Certificate> result = new ArrayList<X509Certificate>();
-        PemObject o;
-        while ((o = pr.readPemObject()) != null) {
-            if (o.getType().equals("CERTIFICATE")) {
-                Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
-                result.add((X509Certificate) c);
-            } else {
-                throw new IllegalArgumentException("Unknown type " + o.getType());
+            List<X509Certificate> result = new ArrayList<X509Certificate>();
+            PemObject o;
+            while ((o = pr.readPemObject()) != null) {
+                if (o.getType().equals("CERTIFICATE")) {
+                    Certificate c = cf.generateCertificate(new ByteArrayInputStream(o.getContent()));
+                    result.add((X509Certificate) c);
+                } else {
+                    throw new IllegalArgumentException("Unknown type " + o.getType());
+                }
             }
+            return result;
+        } finally {
+            pr.close();
         }
-        pr.close();
-        return result;
     }
 
     private static Credentials singleton;
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 1b87a41..3090ac1 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -19,7 +19,6 @@
 import android.app.ActivityThread;
 import android.app.Application;
 import android.app.KeyguardManager;
-
 import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Binder;
@@ -32,6 +31,7 @@
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterBlob;
+import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keymaster.KeymasterDefs;
 import android.security.keymaster.OperationResult;
 import android.security.keystore.KeyExpiredException;
@@ -615,6 +615,17 @@
         return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
     }
 
+    public int attestKey(
+            String alias, KeymasterArguments params, KeymasterCertificateChain outChain) {
+        try {
+            return mBinder.attestKey(alias, params, outChain);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
+
+
     /**
      * Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
      * code.
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 65460b5..3a0ff1c 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -22,6 +22,7 @@
 import android.security.KeyStore;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
+import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keymaster.KeymasterDefs;
 
 import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
@@ -46,6 +47,8 @@
 
 import libcore.util.EmptyArray;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.KeyPair;
@@ -57,14 +60,17 @@
 import java.security.SecureRandom;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateParsingException;
 import java.security.cert.X509Certificate;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.ECGenParameterSpec;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -166,6 +172,7 @@
         mOriginalKeymasterAlgorithm = keymasterAlgorithm;
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void initialize(int keysize, SecureRandom random) {
         throw new IllegalArgumentException(
@@ -173,6 +180,7 @@
                 + " required to initialize this KeyPairGenerator");
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void initialize(AlgorithmParameterSpec params, SecureRandom random)
             throws InvalidAlgorithmParameterException {
@@ -447,6 +455,69 @@
                     + ", but the user has not yet entered the credential");
         }
 
+        byte[] additionalEntropy =
+                KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
+                        mRng, (mKeySizeBits + 7) / 8);
+
+        Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
+        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + mEntryAlias;
+        boolean success = false;
+        try {
+            generateKeystoreKeyPair(
+                    privateKeyAlias, constructKeyGenerationArguments(), additionalEntropy, flags);
+            KeyPair keyPair = loadKeystoreKeyPair(privateKeyAlias);
+
+            storeCertificateChain(flags, createCertificateChain(privateKeyAlias, keyPair));
+
+            success = true;
+            return keyPair;
+        } finally {
+            if (!success) {
+                Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
+            }
+        }
+    }
+
+    private Iterable<byte[]> createCertificateChain(final String privateKeyAlias, KeyPair keyPair)
+            throws ProviderException {
+        byte[] challenge = mSpec.getAttestationChallenge();
+        if (challenge != null) {
+            KeymasterArguments args = new KeymasterArguments();
+            args.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, challenge);
+            return getAttestationChain(privateKeyAlias, keyPair, args);
+        }
+
+        // Very short certificate chain in the non-attestation case.
+        return Collections.singleton(generateSelfSignedCertificateBytes(keyPair));
+    }
+
+    private void generateKeystoreKeyPair(final String privateKeyAlias, KeymasterArguments args,
+            byte[] additionalEntropy, final int flags) throws ProviderException {
+        KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
+        int errorCode = mKeyStore.generateKey(privateKeyAlias, args, additionalEntropy,
+                mEntryUid, flags, resultingKeyCharacteristics);
+        if (errorCode != KeyStore.NO_ERROR) {
+            throw new ProviderException(
+                    "Failed to generate key pair", KeyStore.getKeyStoreException(errorCode));
+        }
+    }
+
+    private KeyPair loadKeystoreKeyPair(final String privateKeyAlias) throws ProviderException {
+        try {
+            KeyPair result  = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
+                    mKeyStore, privateKeyAlias, mEntryUid);
+            if (!mJcaKeyAlgorithm.equalsIgnoreCase(result.getPrivate().getAlgorithm())) {
+                throw new ProviderException(
+                        "Generated key pair algorithm does not match requested algorithm: "
+                                + result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm);
+            }
+            return result;
+        } catch (UnrecoverableKeyException e) {
+            throw new ProviderException("Failed to load generated key pair from keystore", e);
+        }
+    }
+
+    private KeymasterArguments constructKeyGenerationArguments() {
         KeymasterArguments args = new KeymasterArguments();
         args.addUnsignedInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
         args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
@@ -466,73 +537,72 @@
                 mSpec.getKeyValidityForConsumptionEnd());
         addAlgorithmSpecificParameters(args);
 
-        byte[] additionalEntropy =
-                KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
-                        mRng, (mKeySizeBits + 7) / 8);
+        if (mSpec.isUniqueIdIncluded())
+            args.addBoolean(KeymasterDefs.KM_TAG_INCLUDE_UNIQUE_ID);
 
-        final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + mEntryAlias;
-        boolean success = false;
-        try {
-            Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
-            KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
-            int errorCode = mKeyStore.generateKey(
-                    privateKeyAlias,
-                    args,
-                    additionalEntropy,
-                    mEntryUid,
-                    flags,
-                    resultingKeyCharacteristics);
-            if (errorCode != KeyStore.NO_ERROR) {
-                throw new ProviderException(
-                        "Failed to generate key pair", KeyStore.getKeyStoreException(errorCode));
-            }
+        return args;
+    }
 
-            KeyPair result;
-            try {
-                result = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
-                        mKeyStore, privateKeyAlias, mEntryUid);
-            } catch (UnrecoverableKeyException e) {
-                throw new ProviderException("Failed to load generated key pair from keystore", e);
-            }
+    private void storeCertificateChain(final int flags, Iterable<byte[]> iterable)
+            throws ProviderException {
+        Iterator<byte[]> iter = iterable.iterator();
+        storeCertificate(
+                Credentials.USER_CERTIFICATE, iter.next(), flags, "Failed to store certificate");
 
-            if (!mJcaKeyAlgorithm.equalsIgnoreCase(result.getPrivate().getAlgorithm())) {
-                throw new ProviderException(
-                        "Generated key pair algorithm does not match requested algorithm: "
-                        + result.getPrivate().getAlgorithm() + " vs " + mJcaKeyAlgorithm);
-            }
-
-            final X509Certificate cert;
-            try {
-                cert = generateSelfSignedCertificate(result.getPrivate(), result.getPublic());
-            } catch (Exception e) {
-                throw new ProviderException("Failed to generate self-signed certificate", e);
-            }
-
-            byte[] certBytes;
-            try {
-                certBytes = cert.getEncoded();
-            } catch (CertificateEncodingException e) {
-                throw new ProviderException(
-                        "Failed to obtain encoded form of self-signed certificate", e);
-            }
-
-            int insertErrorCode = mKeyStore.insert(
-                    Credentials.USER_CERTIFICATE + mEntryAlias,
-                    certBytes,
-                    mEntryUid,
-                    flags);
-            if (insertErrorCode != KeyStore.NO_ERROR) {
-                throw new ProviderException("Failed to store self-signed certificate",
-                        KeyStore.getKeyStoreException(insertErrorCode));
-            }
-
-            success = true;
-            return result;
-        } finally {
-            if (!success) {
-                Credentials.deleteAllTypesForAlias(mKeyStore, mEntryAlias, mEntryUid);
-            }
+        if (!iter.hasNext()) {
+            return;
         }
+
+        ByteArrayOutputStream certificateConcatenationStream = new ByteArrayOutputStream();
+        while (iter.hasNext()) {
+            byte[] data = iter.next();
+            certificateConcatenationStream.write(data, 0, data.length);
+        }
+
+        storeCertificate(Credentials.CA_CERTIFICATE, certificateConcatenationStream.toByteArray(),
+                flags, "Failed to store attestation CA certificate");
+    }
+
+    private void storeCertificate(String prefix, byte[] certificateBytes, final int flags,
+            String failureMessage) throws ProviderException {
+        int insertErrorCode = mKeyStore.insert(
+                prefix + mEntryAlias,
+                certificateBytes,
+                mEntryUid,
+                flags);
+        if (insertErrorCode != KeyStore.NO_ERROR) {
+            throw new ProviderException(failureMessage,
+                    KeyStore.getKeyStoreException(insertErrorCode));
+        }
+    }
+
+    private byte[] generateSelfSignedCertificateBytes(KeyPair keyPair) throws ProviderException {
+        try {
+            return generateSelfSignedCertificate(keyPair.getPrivate(), keyPair.getPublic())
+                    .getEncoded();
+        } catch (IOException | CertificateParsingException e) {
+            throw new ProviderException("Failed to generate self-signed certificate", e);
+        } catch (CertificateEncodingException e) {
+            throw new ProviderException(
+                    "Failed to obtain encoded form of self-signed certificate", e);
+        }
+    }
+
+    private Iterable<byte[]> getAttestationChain(String privateKeyAlias,
+            KeyPair keyPair, KeymasterArguments args)
+                    throws ProviderException {
+        KeymasterCertificateChain outChain = new KeymasterCertificateChain();
+        int errorCode = mKeyStore.attestKey(privateKeyAlias, args, outChain);
+        if (errorCode != KeyStore.NO_ERROR) {
+            throw new ProviderException("Failed to generate attestation certificate chain",
+                    KeyStore.getKeyStoreException(errorCode));
+        }
+        Collection<byte[]> chain = outChain.getCertificates();
+        if (chain.size() < 2) {
+            throw new ProviderException("Attestation certificate chain contained "
+                    + chain.size() + " entries. At least two are required.");
+        }
+        return chain;
     }
 
     private void addAlgorithmSpecificParameters(KeymasterArguments keymasterArgs) {
@@ -548,8 +618,8 @@
         }
     }
 
-    private X509Certificate generateSelfSignedCertificate(
-            PrivateKey privateKey, PublicKey publicKey) throws Exception {
+    private X509Certificate generateSelfSignedCertificate(PrivateKey privateKey,
+            PublicKey publicKey) throws CertificateParsingException, IOException {
         String signatureAlgorithm =
                 getCertificateSignatureAlgorithm(mKeymasterAlgorithm, mKeySizeBits, mSpec);
         if (signatureAlgorithm == null) {
@@ -587,7 +657,7 @@
 
     @SuppressWarnings("deprecation")
     private X509Certificate generateSelfSignedCertificateWithFakeSignature(
-            PublicKey publicKey) throws Exception {
+            PublicKey publicKey) throws IOException, CertificateParsingException {
         V3TBSCertificateGenerator tbsGenerator = new V3TBSCertificateGenerator();
         ASN1ObjectIdentifier sigAlgOid;
         AlgorithmIdentifier sigAlgId;
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index add199f..f3fd129 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -250,6 +250,8 @@
     private final boolean mRandomizedEncryptionRequired;
     private final boolean mUserAuthenticationRequired;
     private final int mUserAuthenticationValidityDurationSeconds;
+    private final byte[] mAttestationChallenge;
+    private final boolean mUniqueIdIncluded;
 
     /**
      * @hide should be built with Builder
@@ -273,7 +275,9 @@
             @KeyProperties.BlockModeEnum String[] blockModes,
             boolean randomizedEncryptionRequired,
             boolean userAuthenticationRequired,
-            int userAuthenticationValidityDurationSeconds) {
+            int userAuthenticationValidityDurationSeconds,
+            byte[] attestationChallenge,
+            boolean uniqueIdIncluded) {
         if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
         }
@@ -315,6 +319,8 @@
         mRandomizedEncryptionRequired = randomizedEncryptionRequired;
         mUserAuthenticationRequired = userAuthenticationRequired;
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+        mAttestationChallenge = Utils.cloneIfNotNull(attestationChallenge);
+        mUniqueIdIncluded = uniqueIdIncluded;
     }
 
     /**
@@ -539,6 +545,48 @@
     }
 
     /**
+     * Returns the attestation challenge value that will be placed in attestation certificate for
+     * this key pair.
+     *
+     * <p>If this method returns non-{@code null}, the public key certificate for this key pair will
+     * contain an extension that describes the details of the key's configuration and
+     * authorizations, including the content of the attestation challenge value. If the key is in
+     * secure hardware, and if the secure hardware supports attestation, the certificate will be
+     * signed by a chain of certificates rooted at a trustworthy CA key. Otherwise the chain will
+     * be rooted at an untrusted certificate.
+     *
+     * <p>If this method returns {@code null}, and the spec is used to generate an asymmetric (RSA
+     * or EC) key pair, the public key will have a self-signed certificate if it has purpose {@link
+     * KeyProperties#PURPOSE_SIGN} (see {@link #KeyGenParameterSpec(String, int)). If does not have
+     * purpose {@link KeyProperties#PURPOSE_SIGN}, it will have a fake certificate.
+     *
+     * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
+     * {@link KeyGenParameterSpec} with {@link #hasAttestationCertificate()} returning
+     * non-{@code null} is used to generate a symmetric (AES or HMAC) key,
+     * {@link KeyGenerator#generateKey())} will throw
+     * {@link java.security.InvalidAlgorithmParameterException}.
+     *
+     * @see Builder#setAttestationChallenge(byte[])
+     */
+    /*
+     * TODO(swillden): Update this documentation to describe the hardware and software root keys,
+     * including information about CRL/OCSP services for discovering revocations, and to link to
+     * documentation of the extension format and content.
+     */
+    public byte[] getAttestationChallenge() {
+        return Utils.cloneIfNotNull(mAttestationChallenge);
+    }
+
+    /**
+     * @hide This is a system-only API
+     *
+     * Returns {@code true} if the attestation certificate will contain a unique ID field.
+     */
+    public boolean isUniqueIdIncluded() {
+        return mUniqueIdIncluded;
+    }
+
+    /**
      * Builder of {@link KeyGenParameterSpec} instances.
      */
     public final static class Builder {
@@ -562,6 +610,8 @@
         private boolean mRandomizedEncryptionRequired = true;
         private boolean mUserAuthenticationRequired;
         private int mUserAuthenticationValidityDurationSeconds = -1;
+        private byte[] mAttestationChallenge = null;
+        private boolean mUniqueIdIncluded = false;
 
         /**
          * Creates a new instance of the {@code Builder}.
@@ -957,6 +1007,59 @@
             return this;
         }
 
+        /*
+         * TODO(swillden): Update this documentation to describe the hardware and software root
+         * keys, including information about CRL/OCSP services for discovering revocations, and to
+         * link to documentation of the extension format and content.
+         */
+        /**
+         * Sets whether an attestation certificate will be generated for this key pair, and what
+         * challenge value will be placed in the certificate.  The attestation certificate chain
+         * can be retrieved with with {@link java.security.KeyStore#getCertificateChain(String)}.
+         *
+         * <p>If {@code attestationChallenge} is not {@code null}, the public key certificate for
+         * this key pair will contain an extension that describes the details of the key's
+         * configuration and authorizations, including the {@code attestationChallenge} value. If
+         * the key is in secure hardware, and if the secure hardware supports attestation, the
+         * certificate will be signed by a chain of certificates rooted at a trustworthy CA key.
+         * Otherwise the chain will be rooted at an untrusted certificate.
+         *
+         * <p>The purpose of the challenge value is to enable relying parties to verify that the key
+         * was created in response to a specific request. If attestation is desired but no
+         * challenged is needed, any non-{@code null} value may be used, including an empty byte
+         * array.
+         *
+         * <p>If {@code attestationChallenge} is {@code null}, and this spec is used to generate an
+         * asymmetric (RSA or EC) key pair, the public key certificate will be self-signed if the
+         * key has purpose {@link KeyProperties#PURPOSE_SIGN} (see
+         * {@link #KeyGenParameterSpec(String, int)). If the key does not have purpose
+         * {@link KeyProperties#PURPOSE_SIGN}, it is not possible to use the key to sign a
+         * certificate, so the public key certificate will contain a dummy signature.
+         *
+         * <p>Symmetric keys, such as AES and HMAC keys, do not have public key certificates. If a
+         * {@code getAttestationChallenge} returns non-{@code null} and the spec is used to
+         * generate a symmetric (AES or HMAC) key, {@link KeyGenerator#generateKey()} will throw
+         * {@link java.security.InvalidAlgorithmParameterException}.
+         *
+         * @see Builder#setAttestationChallenge(String attestationChallenge)
+         */
+        @NonNull
+        public Builder setAttestationChallenge(byte[] attestationChallenge) {
+            mAttestationChallenge = attestationChallenge;
+            return this;
+        }
+
+        /**
+         * @hide Only system apps can use this method.
+         *
+         * Sets whether to include a temporary unique ID field in the attestation certificate.
+         */
+        @NonNull
+        public Builder setUniqueIdIncluded(boolean uniqueIdIncluded) {
+            mUniqueIdIncluded = uniqueIdIncluded;
+            return this;
+        }
+
         /**
          * Builds an instance of {@code KeyGenParameterSpec}.
          */
@@ -981,7 +1084,9 @@
                     mBlockModes,
                     mRandomizedEncryptionRequired,
                     mUserAuthenticationRequired,
-                    mUserAuthenticationValidityDurationSeconds);
+                    mUserAuthenticationValidityDurationSeconds,
+                    mAttestationChallenge,
+                    mUniqueIdIncluded);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/Utils.java b/keystore/java/android/security/keystore/Utils.java
index 9bec682..5722c7b 100644
--- a/keystore/java/android/security/keystore/Utils.java
+++ b/keystore/java/android/security/keystore/Utils.java
@@ -29,4 +29,8 @@
     static Date cloneIfNotNull(Date value) {
         return (value != null) ? (Date) value.clone() : null;
     }
+
+    static byte[] cloneIfNotNull(byte[] value) {
+        return (value != null) ? value.clone() : null;
+    }
 }
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 1d9fe35..3277c36 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -2236,7 +2236,7 @@
     // See if any of the regions is better than the other
     const int region_comparison = localeDataCompareRegions(
             country, o.country,
-            language, localeScript, requested->country);
+            language, requested->localeScript, requested->country);
     if (region_comparison != 0) {
         return (region_comparison > 0);
     }
@@ -2526,17 +2526,34 @@
 
         // For backward compatibility and supporting private-use locales, we
         // fall back to old behavior if we couldn't determine the script for
-        // either of the desired locale or the provided locale.
-        if (localeScript[0] == '\0' || localeScript[1] == '\0') {
+        // either of the desired locale or the provided locale. But if we could determine
+        // the scripts, they should be the same for the locales to match.
+        bool countriesMustMatch = false;
+        char computed_script[4];
+        const char* script;
+        if (settings.localeScript[0] == '\0') { // could not determine the request's script
+            countriesMustMatch = true;
+        } else {
+            if (localeScript[0] == '\0') { // script was not provided, so we try to compute it
+                localeDataComputeScript(computed_script, language, country);
+                if (computed_script[0] == '\0') { // we could not compute the script
+                    countriesMustMatch = true;
+                } else {
+                    script = computed_script;
+                }
+            } else { // script was provided, so just use it
+                script = localeScript;
+            }
+        }
+
+        if (countriesMustMatch) {
             if (country[0] != '\0'
                 && (country[0] != settings.country[0]
                     || country[1] != settings.country[1])) {
                 return false;
             }
         } else {
-            // But if we could determine the scripts, they should be the same
-            // for the locales to match.
-            if (memcmp(localeScript, settings.localeScript, sizeof(localeScript)) != 0) {
+            if (memcmp(script, settings.localeScript, sizeof(settings.localeScript)) != 0) {
                 return false;
             }
         }
diff --git a/libs/androidfw/tests/ConfigLocale_test.cpp b/libs/androidfw/tests/ConfigLocale_test.cpp
index 7b38640..4b8d65c 100644
--- a/libs/androidfw/tests/ConfigLocale_test.cpp
+++ b/libs/androidfw/tests/ConfigLocale_test.cpp
@@ -371,6 +371,19 @@
     EXPECT_TRUE(supported.match(requested));
 }
 
+TEST(ConfigLocaleTest, match_emptyScript) {
+    ResTable_config supported, requested;
+
+    fillIn("fr", "FR", NULL, NULL, &supported);
+    fillIn("fr", "CA", NULL, NULL, &requested);
+
+    // emulate packages built with older AAPT
+    memset(supported.localeScript, '\0', 4);
+    supported.localeScriptWasProvided = false;
+
+    EXPECT_TRUE(supported.match(requested));
+}
+
 TEST(ConfigLocaleTest, isLocaleBetterThan_basics) {
     ResTable_config config1, config2, request;
 
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 7b43947..6257122 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -144,20 +144,8 @@
     external/skia/include/private \
     external/skia/src/core
 
-hwui_shared_libraries := \
-    liblog \
-    libcutils \
-    libutils \
-    libEGL \
-    libGLESv2 \
-    libskia \
-    libui \
-    libgui \
-    libprotobuf-cpp-lite \
-
 ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
     hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT
-    hwui_shared_libraries += libRS libRScpp
     hwui_c_includes += \
         $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) \
         frameworks/rs/cpp \
@@ -180,12 +168,15 @@
 
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := libhwui_static
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_CFLAGS := $(hwui_cflags)
 LOCAL_SRC_FILES := $(hwui_src_files)
 LOCAL_C_INCLUDES := $(hwui_c_includes) $(call hwui_proto_include)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(hwui_c_includes) $(call hwui_proto_include)
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+        $(LOCAL_PATH) \
+        $(hwui_c_includes) \
+        $(call hwui_proto_include)
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_STATIC_LIBRARY)
 
 # ------------------------
@@ -196,7 +187,6 @@
 
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := libhwui_static_null_gpu
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_CFLAGS := \
         $(hwui_cflags) \
         -DHWUI_NULL_GPU
@@ -205,8 +195,12 @@
         debug/nullegl.cpp \
         debug/nullgles.cpp
 LOCAL_C_INCLUDES := $(hwui_c_includes) $(call hwui_proto_include)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(hwui_c_includes) $(call hwui_proto_include)
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+        $(LOCAL_PATH) \
+        $(hwui_c_includes) \
+        $(call hwui_proto_include)
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_STATIC_LIBRARY)
 
 # ------------------------
@@ -218,8 +212,9 @@
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE := libhwui
 LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_SHARED_LIBRARY)
 
 # ------------------------
@@ -230,7 +225,6 @@
 
 LOCAL_MODULE := hwui_unit_tests
 LOCAL_MODULE_TAGS := tests
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_STATIC_LIBRARIES := libhwui_static_null_gpu
 LOCAL_CFLAGS := \
         $(hwui_cflags) \
@@ -238,7 +232,6 @@
 
 LOCAL_SRC_FILES += \
     $(hwui_test_common_src_files) \
-    tests/unit/BufferPoolTests.cpp \
     tests/unit/CanvasStateTests.cpp \
     tests/unit/ClipAreaTests.cpp \
     tests/unit/CrashHandlerInjector.cpp \
@@ -263,6 +256,7 @@
         tests/unit/RecordingCanvasTests.cpp
 endif
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_NATIVE_TEST)
 
 # ------------------------
@@ -278,7 +272,6 @@
 LOCAL_MULTILIB := both
 LOCAL_MODULE_STEM_32 := hwuitest
 LOCAL_MODULE_STEM_64 := hwuitest64
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_CFLAGS := $(hwui_cflags)
 
 # set to libhwui_static_null_gpu to skip actual GL commands
@@ -289,6 +282,7 @@
     tests/macrobench/TestSceneRunner.cpp \
     tests/macrobench/main.cpp
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_EXECUTABLE)
 
 # ------------------------
@@ -303,7 +297,6 @@
 LOCAL_MULTILIB := both
 LOCAL_MODULE_STEM_32 := hwuimicro
 LOCAL_MODULE_STEM_64 := hwuimicro64
-LOCAL_SHARED_LIBRARIES := $(hwui_shared_libraries)
 LOCAL_CFLAGS := \
         $(hwui_cflags) \
         -DHWUI_NULL_GPU
@@ -317,11 +310,13 @@
     tests/microbench/DisplayListCanvasBench.cpp \
     tests/microbench/LinearAllocatorBench.cpp \
     tests/microbench/PathParserBench.cpp \
-    tests/microbench/ShadowBench.cpp
+    tests/microbench/ShadowBench.cpp \
+    tests/microbench/TaskManagerBench.cpp
 
 ifeq (true, $(HWUI_NEW_OPS))
     LOCAL_SRC_FILES += \
         tests/microbench/FrameBuilderBench.cpp
 endif
 
+include $(LOCAL_PATH)/hwui_static_deps.mk
 include $(BUILD_EXECUTABLE)
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 7bd2b24..294edb6 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -33,6 +33,7 @@
 
 BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
         : mTarget(nullptr)
+        , mStagingTarget(nullptr)
         , mFinalValue(finalValue)
         , mDeltaValue(0)
         , mFromValue(0)
@@ -42,7 +43,8 @@
         , mStartTime(0)
         , mDuration(300)
         , mStartDelay(0)
-        , mMayRunAsync(true) {
+        , mMayRunAsync(true)
+        , mPlayTime(0) {
 }
 
 BaseRenderNodeAnimator::~BaseRenderNodeAnimator() {
@@ -81,26 +83,129 @@
 }
 
 void BaseRenderNodeAnimator::attach(RenderNode* target) {
-    mTarget = target;
+    mStagingTarget = target;
     onAttached();
 }
 
+void BaseRenderNodeAnimator::start() {
+    mStagingPlayState = PlayState::Running;
+    mStagingRequests.push_back(Request::Start);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::cancel() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::Cancel);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::reset() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::Reset);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::reverse() {
+    mStagingPlayState = PlayState::Reversing;
+    mStagingRequests.push_back(Request::Reverse);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::end() {
+    mStagingPlayState = PlayState::Finished;
+    mStagingRequests.push_back(Request::End);
+    onStagingPlayStateChanged();
+}
+
+void BaseRenderNodeAnimator::resolveStagingRequest(Request request) {
+    switch (request) {
+    case Request::Start:
+        mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
+                        mPlayTime : 0;
+        mPlayState = PlayState::Running;
+        break;
+    case Request::Reverse:
+        mPlayTime = (mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) ?
+                        mPlayTime : mDuration;
+        mPlayState = PlayState::Reversing;
+        break;
+    case Request::Reset:
+        mPlayTime = 0;
+        mPlayState = PlayState::Finished;
+        break;
+    case Request::Cancel:
+        mPlayState = PlayState::Finished;
+        break;
+    case Request::End:
+        mPlayTime = mPlayState == PlayState::Reversing ? 0 : mDuration;
+        mPlayState = PlayState::Finished;
+        break;
+    default:
+        LOG_ALWAYS_FATAL("Invalid staging request: %d", static_cast<int>(request));
+    };
+}
+
 void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
+    if (mStagingTarget) {
+        RenderNode* oldTarget = mTarget;
+        mTarget = mStagingTarget;
+        mStagingTarget = nullptr;
+        if (oldTarget && oldTarget != mTarget) {
+            oldTarget->onAnimatorTargetChanged(this);
+        }
+    }
+
     if (!mHasStartValue) {
         doSetStartValue(getValue(mTarget));
     }
-    if (mStagingPlayState > mPlayState) {
-        if (mStagingPlayState == PlayState::Restarted) {
-            mStagingPlayState = PlayState::Running;
+
+    if (!mStagingRequests.empty()) {
+        // Keep track of the play state and play time before they are changed when
+        // staging requests are resolved.
+        nsecs_t currentPlayTime = mPlayTime;
+        PlayState prevFramePlayState = mPlayState;
+
+        // Resolve staging requests one by one.
+        for (Request request : mStagingRequests) {
+            resolveStagingRequest(request);
         }
-        mPlayState = mStagingPlayState;
-        // Oh boy, we're starting! Man the battle stations!
-        if (mPlayState == PlayState::Running) {
-            transitionToRunning(context);
-        } else if (mPlayState == PlayState::Finished) {
+        mStagingRequests.clear();
+
+        if (mStagingPlayState == PlayState::Finished) {
+            // Set the staging play time and end the animation
+            updatePlayTime(mPlayTime);
             callOnFinishedListener(context);
+        } else if (mStagingPlayState == PlayState::Running
+                || mStagingPlayState == PlayState::Reversing) {
+            bool changed = currentPlayTime != mPlayTime || prevFramePlayState != mStagingPlayState;
+            if (prevFramePlayState != mStagingPlayState) {
+                transitionToRunning(context);
+            }
+            if (changed) {
+                // Now we need to seek to the stagingPlayTime (i.e. the animation progress that was
+                // requested from UI thread). It is achieved by modifying mStartTime, such that
+                // current time - mStartTime = stagingPlayTime (or mDuration -stagingPlayTime in the
+                // case of reversing)
+                nsecs_t currentFrameTime = context.frameTimeMs();
+                if (mPlayState == PlayState::Reversing) {
+                    // Reverse is not supported for animations with a start delay, so here we
+                    // assume no start delay.
+                    mStartTime = currentFrameTime  - (mDuration - mPlayTime);
+                } else {
+                    // Animation should play forward
+                    if (mPlayTime == 0) {
+                        // If the request is to start from the beginning, include start delay.
+                        mStartTime = currentFrameTime + mStartDelay;
+                    } else {
+                        // If the request is to seek to a non-zero play time, then we skip start
+                        // delay.
+                        mStartTime = currentFrameTime - mPlayTime;
+                    }
+                }
+            }
         }
     }
+    onPushStaging();
 }
 
 void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) {
@@ -136,37 +241,37 @@
 
     // This should be set before setValue() so animators can query this time when setValue
     // is called.
-    nsecs_t currentFrameTime = context.frameTimeMs();
-    onPlayTimeChanged(currentFrameTime - mStartTime);
+    nsecs_t currentPlayTime = context.frameTimeMs() - mStartTime;
+    bool finished = updatePlayTime(currentPlayTime);
+    if (finished && mPlayState != PlayState::Finished) {
+        mPlayState = PlayState::Finished;
+        callOnFinishedListener(context);
+    }
+    return finished;
+}
 
+bool BaseRenderNodeAnimator::updatePlayTime(nsecs_t playTime) {
+    mPlayTime = mPlayState == PlayState::Reversing ? mDuration - playTime : playTime;
+    onPlayTimeChanged(mPlayTime);
     // If BaseRenderNodeAnimator is handling the delay (not typical), then
     // because the staging properties reflect the final value, we always need
     // to call setValue even if the animation isn't yet running or is still
     // being delayed as we need to override the staging value
-    if (mStartTime > context.frameTimeMs()) {
+    if (playTime < 0) {
         setValue(mTarget, mFromValue);
         return false;
     }
 
     float fraction = 1.0f;
-
-    if (mPlayState == PlayState::Running && mDuration > 0) {
-        fraction = (float)(currentFrameTime - mStartTime) / mDuration;
+    if ((mPlayState == PlayState::Running || mPlayState == PlayState::Reversing) && mDuration > 0) {
+        fraction = mPlayTime / (float) mDuration;
     }
-    if (fraction >= 1.0f) {
-        fraction = 1.0f;
-        mPlayState = PlayState::Finished;
-    }
+    fraction = MathUtils::clamp(fraction, 0.0f, 1.0f);
 
     fraction = mInterpolator->interpolate(fraction);
     setValue(mTarget, mFromValue + (mDeltaValue * fraction));
 
-    if (mPlayState == PlayState::Finished) {
-        callOnFinishedListener(context);
-        return true;
-    }
-
-    return false;
+    return playTime >= mDuration;
 }
 
 void BaseRenderNodeAnimator::forceEndNow(AnimationContext& context) {
@@ -215,18 +320,36 @@
 
 void RenderPropertyAnimator::onAttached() {
     if (!mHasStartValue
-            && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
-        setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
+            && mStagingTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
+        setStartValue((mStagingTarget->stagingProperties().*mPropertyAccess->getter)());
     }
 }
 
 void RenderPropertyAnimator::onStagingPlayStateChanged() {
     if (mStagingPlayState == PlayState::Running) {
-        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        if (mStagingTarget) {
+            (mStagingTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        } else {
+            // In the case of start delay where stagingTarget has been sync'ed over and null'ed
+            // we delay the properties update to push staging.
+            mShouldUpdateStagingProperties = true;
+        }
     } else if (mStagingPlayState == PlayState::Finished) {
         // We're being canceled, so make sure that whatever values the UI thread
         // is observing for us is pushed over
+        mShouldSyncPropertyFields = true;
+    }
+}
+
+void RenderPropertyAnimator::onPushStaging() {
+    if (mShouldUpdateStagingProperties) {
+        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+        mShouldUpdateStagingProperties = false;
+    }
+
+    if (mShouldSyncPropertyFields) {
         mTarget->setPropertyFieldsDirty(dirtyMask());
+        mShouldSyncPropertyFields = false;
     }
 }
 
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 2c9c9c3..fdae0f3 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -24,6 +24,8 @@
 
 #include "utils/Macros.h"
 
+#include <vector>
+
 namespace android {
 namespace uirenderer {
 
@@ -59,14 +61,14 @@
         mMayRunAsync = mayRunAsync;
     }
     bool mayRunAsync() { return mMayRunAsync; }
-    ANDROID_API void start() {
-        if (mStagingPlayState == PlayState::NotStarted) {
-            mStagingPlayState = PlayState::Running;
-        } else {
-            mStagingPlayState = PlayState::Restarted;
-        }
-        onStagingPlayStateChanged(); }
-    ANDROID_API void end() { mStagingPlayState = PlayState::Finished; onStagingPlayStateChanged(); }
+    ANDROID_API void start();
+    ANDROID_API void reset();
+    ANDROID_API void reverse();
+    // Terminates the animation at its current progress.
+    ANDROID_API void cancel();
+
+    // Terminates the animation and skip to the end of the animation.
+    ANDROID_API void end();
 
     void attach(RenderNode* target);
     virtual void onAttached() {}
@@ -74,36 +76,42 @@
     void pushStaging(AnimationContext& context);
     bool animate(AnimationContext& context);
 
-    bool isRunning() { return mPlayState == PlayState::Running; }
+    bool isRunning() { return mPlayState == PlayState::Running
+            || mPlayState == PlayState::Reversing; }
     bool isFinished() { return mPlayState == PlayState::Finished; }
     float finalValue() { return mFinalValue; }
 
     ANDROID_API virtual uint32_t dirtyMask() = 0;
 
     void forceEndNow(AnimationContext& context);
+    RenderNode* target() { return mTarget; }
+    RenderNode* stagingTarget() { return mStagingTarget; }
 
 protected:
     // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
     // thread and Render Thread animation state, respectively.
     // From the UI thread, mStagingPlayState transition looks like
-    // NotStarted -> Running -> Finished
-    //                ^            |
-    //                |            |
-    //            Restarted <------
+    // NotStarted -> Running/Reversing -> Finished
+    //                ^                     |
+    //                |                     |
+    //                ----------------------
     // Note: For mStagingState, the Finished state (optional) is only set when the animation is
     // terminated by user.
     //
     // On Render Thread, mPlayState transition:
-    // NotStart -> Running -> Finished
-    //                ^            |
-    //                |            |
-    //                -------------
+    // NotStart -> Running/Reversing-> Finished
+    //                ^                 |
+    //                |                 |
+    //                ------------------
+    // Note that if the animation is in Running/Reversing state, calling start or reverse again
+    // would do nothing if the animation has the same play direction as the request; otherwise,
+    // the animation would start from where it is and change direction (i.e. Reversing <-> Running)
 
     enum class PlayState {
         NotStarted,
         Running,
+        Reversing,
         Finished,
-        Restarted,
     };
 
     BaseRenderNodeAnimator(float finalValue);
@@ -111,14 +119,15 @@
 
     virtual float getValue(RenderNode* target) const = 0;
     virtual void setValue(RenderNode* target, float value) = 0;
-    RenderNode* target() { return mTarget; }
 
     void callOnFinishedListener(AnimationContext& context);
 
     virtual void onStagingPlayStateChanged() {}
     virtual void onPlayTimeChanged(nsecs_t playTime) {}
+    virtual void onPushStaging() {}
 
     RenderNode* mTarget;
+    RenderNode* mStagingTarget;
 
     float mFinalValue;
     float mDeltaValue;
@@ -132,13 +141,28 @@
     nsecs_t mDuration;
     nsecs_t mStartDelay;
     bool mMayRunAsync;
+    // Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being
+    // the beginning of the animation, will reach mDuration at the end of an animation.
+    nsecs_t mPlayTime;
 
     sp<AnimationListener> mListener;
 
 private:
+    enum class Request {
+        Start,
+        Reverse,
+        Reset,
+        Cancel,
+        End
+    };
     inline void checkMutable();
     virtual void transitionToRunning(AnimationContext& context);
     void doSetStartValue(float value);
+    bool updatePlayTime(nsecs_t playTime);
+    void resolveStagingRequest(Request request);
+
+    std::vector<Request> mStagingRequests;
+
 };
 
 class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -167,6 +191,7 @@
     virtual void setValue(RenderNode* target, float value) override;
     virtual void onAttached() override;
     virtual void onStagingPlayStateChanged() override;
+    virtual void onPushStaging() override;
 
 private:
     typedef bool (RenderProperties::*SetFloatProperty)(float value);
@@ -176,6 +201,8 @@
     const PropertyAccessors* mPropertyAccess;
 
     static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
+    bool mShouldSyncPropertyFields = false;
+    bool mShouldUpdateStagingProperties = false;
 };
 
 class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index cd30b18..2198fcc 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -27,9 +27,8 @@
 
 using namespace std;
 
-static void unref(BaseRenderNodeAnimator* animator) {
+static void detach(sp<BaseRenderNodeAnimator>& animator) {
     animator->detach();
-    animator->decStrong(nullptr);
 }
 
 AnimatorManager::AnimatorManager(RenderNode& parent)
@@ -38,14 +37,28 @@
 }
 
 AnimatorManager::~AnimatorManager() {
-    for_each(mNewAnimators.begin(), mNewAnimators.end(), unref);
-    for_each(mAnimators.begin(), mAnimators.end(), unref);
+    for_each(mNewAnimators.begin(), mNewAnimators.end(), detach);
+    for_each(mAnimators.begin(), mAnimators.end(), detach);
 }
 
 void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
-    animator->incStrong(nullptr);
+    RenderNode* stagingTarget = animator->stagingTarget();
+    if (stagingTarget == &mParent) {
+        return;
+    }
+    mNewAnimators.emplace_back(animator.get());
+    // If the animator is already attached to other RenderNode, remove it from that RenderNode's
+    // new animator list. This ensures one animator only ends up in one newAnimatorList during one
+    // frame, even when it's added multiple times to multiple targets.
+    if (stagingTarget) {
+        stagingTarget->removeAnimator(animator);
+    }
     animator->attach(&mParent);
-    mNewAnimators.push_back(animator.get());
+}
+
+void AnimatorManager::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+    mNewAnimators.erase(std::remove(mNewAnimators.begin(), mNewAnimators.end(), animator),
+            mNewAnimators.end());
 }
 
 void AnimatorManager::setAnimationHandle(AnimationHandle* handle) {
@@ -56,38 +69,40 @@
             &mParent, mParent.getName());
 }
 
-template<typename T>
-static void move_all(T& source, T& dest) {
-    dest.reserve(source.size() + dest.size());
-    for (typename T::iterator it = source.begin(); it != source.end(); it++) {
-        dest.push_back(*it);
-    }
-    source.clear();
-}
-
 void AnimatorManager::pushStaging() {
     if (mNewAnimators.size()) {
         LOG_ALWAYS_FATAL_IF(!mAnimationHandle,
                 "Trying to start new animators on %p (%s) without an animation handle!",
                 &mParent, mParent.getName());
-        // Since this is a straight move, we don't need to inc/dec the ref count
-        move_all(mNewAnimators, mAnimators);
+
+        // Only add new animators that are not already in the mAnimators list
+        for (auto& anim : mNewAnimators) {
+            if (anim->target() != &mParent) {
+                mAnimators.push_back(std::move(anim));
+            }
+        }
+        mNewAnimators.clear();
     }
-    for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
-        (*it)->pushStaging(mAnimationHandle->context());
+    for (auto& animator : mAnimators) {
+        animator->pushStaging(mAnimationHandle->context());
     }
 }
 
+void AnimatorManager::onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
+    LOG_ALWAYS_FATAL_IF(animator->target() == &mParent, "Target has not been changed");
+    mAnimators.erase(std::remove(mAnimators.begin(), mAnimators.end(), animator), mAnimators.end());
+}
+
 class AnimateFunctor {
 public:
     AnimateFunctor(TreeInfo& info, AnimationContext& context)
             : dirtyMask(0), mInfo(info), mContext(context) {}
 
-    bool operator() (BaseRenderNodeAnimator* animator) {
+    bool operator() (sp<BaseRenderNodeAnimator>& animator) {
         dirtyMask |= animator->dirtyMask();
         bool remove = animator->animate(mContext);
         if (remove) {
-            animator->decStrong(nullptr);
+            animator->detach();
         } else {
             if (animator->isRunning()) {
                 mInfo.out.hasAnimations = true;
@@ -129,20 +144,18 @@
 
 uint32_t AnimatorManager::animateCommon(TreeInfo& info) {
     AnimateFunctor functor(info, mAnimationHandle->context());
-    std::vector< BaseRenderNodeAnimator* >::iterator newEnd;
-    newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
+    auto newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor);
     mAnimators.erase(newEnd, mAnimators.end());
     mAnimationHandle->notifyAnimationsRan();
     mParent.mProperties.updateMatrix();
     return functor.dirtyMask;
 }
 
-static void endStagingAnimator(BaseRenderNodeAnimator* animator) {
-    animator->end();
+static void endStagingAnimator(sp<BaseRenderNodeAnimator>& animator) {
+    animator->cancel();
     if (animator->listener()) {
-        animator->listener()->onAnimationFinished(animator);
+        animator->listener()->onAnimationFinished(animator.get());
     }
-    animator->decStrong(nullptr);
 }
 
 void AnimatorManager::endAllStagingAnimators() {
@@ -157,9 +170,8 @@
 public:
     EndActiveAnimatorsFunctor(AnimationContext& context) : mContext(context) {}
 
-    void operator() (BaseRenderNodeAnimator* animator) {
+    void operator() (sp<BaseRenderNodeAnimator>& animator) {
         animator->forceEndNow(mContext);
-        animator->decStrong(nullptr);
     }
 
 private:
diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h
index fb75eb8..61f6179 100644
--- a/libs/hwui/AnimatorManager.h
+++ b/libs/hwui/AnimatorManager.h
@@ -39,11 +39,13 @@
     ~AnimatorManager();
 
     void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+    void removeAnimator(const sp<BaseRenderNodeAnimator>& animator);
 
     void setAnimationHandle(AnimationHandle* handle);
     bool hasAnimationHandle() { return mAnimationHandle; }
 
     void pushStaging();
+    void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator);
 
     // Returns the combined dirty mask of all animators run
     uint32_t animate(TreeInfo& info);
@@ -66,9 +68,8 @@
     AnimationHandle* mAnimationHandle;
 
     // To improve the efficiency of resizing & removing from the vector
-    // use manual ref counting instead of sp<>.
-    std::vector<BaseRenderNodeAnimator*> mNewAnimators;
-    std::vector<BaseRenderNodeAnimator*> mAnimators;
+    std::vector< sp<BaseRenderNodeAnimator> > mNewAnimators;
+    std::vector< sp<BaseRenderNodeAnimator> > mAnimators;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index e3a5f3e..f83e1fa 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -201,8 +201,7 @@
 
     renderer.caches().dropShadowCache.setFontRenderer(fontRenderer);
     ShadowTexture* texture = renderer.caches().dropShadowCache.get(
-            op.paint, (const char*) op.glyphs,
-            op.glyphCount, textShadow.radius, op.positions);
+            op.paint, op.glyphs, op.glyphCount, textShadow.radius, op.positions);
     // If the drop shadow exceeds the max texture size or couldn't be
     // allocated, skip drawing
     if (!texture) return;
@@ -277,8 +276,7 @@
     bool forceFinish = (renderType == TextRenderType::Flush);
     bool mustDirtyRenderTarget = renderer.offscreenRenderTarget();
     const Rect* localOpClip = pureTranslate ? &state.computedState.clipRect() : nullptr;
-    fontRenderer.renderPosText(op.paint, localOpClip,
-            (const char*) op.glyphs, op.glyphCount, x, y,
+    fontRenderer.renderPosText(op.paint, localOpClip, op.glyphs, op.glyphCount, x, y,
             op.positions, mustDirtyRenderTarget ? &layerBounds : nullptr, &functor, forceFinish);
 
     if (mustDirtyRenderTarget) {
@@ -701,8 +699,7 @@
 
     bool mustDirtyRenderTarget = renderer.offscreenRenderTarget();
     const Rect localSpaceClip = state.computedState.computeLocalSpaceClip();
-    if (fontRenderer.renderTextOnPath(op.paint, &localSpaceClip,
-            reinterpret_cast<const char*>(op.glyphs), op.glyphCount,
+    if (fontRenderer.renderTextOnPath(op.paint, &localSpaceClip, op.glyphs, op.glyphCount,
             op.path, op.hOffset, op.vOffset,
             mustDirtyRenderTarget ? &layerBounds : nullptr, &functor)) {
         if (mustDirtyRenderTarget) {
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index 3db28c9..5a5845a 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -100,7 +100,7 @@
     static BakedOpState* tryConstruct(LinearAllocator& allocator,
             Snapshot& snapshot, const RecordedOp& recordedOp) {
         if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
-        BakedOpState* bakedState = new (allocator) BakedOpState(
+        BakedOpState* bakedState = allocator.create_trivial<BakedOpState>(
                 allocator, snapshot, recordedOp, false);
         if (bakedState->computedState.clippedBounds.isEmpty()) {
             // bounds are empty, so op is rejected
@@ -124,7 +124,7 @@
                 ? (recordedOp.paint && recordedOp.paint->getStyle() != SkPaint::kFill_Style)
                 : true;
 
-        BakedOpState* bakedState = new (allocator) BakedOpState(
+        BakedOpState* bakedState = allocator.create_trivial<BakedOpState>(
                 allocator, snapshot, recordedOp, expandForStroke);
         if (bakedState->computedState.clippedBounds.isEmpty()) {
             // bounds are empty, so op is rejected
@@ -140,16 +140,12 @@
         if (CC_UNLIKELY(snapshot.getRenderTargetClip().isEmpty())) return nullptr;
 
         // clip isn't empty, so construct the op
-        return new (allocator) BakedOpState(allocator, snapshot, shadowOpPtr);
+        return allocator.create_trivial<BakedOpState>(allocator, snapshot, shadowOpPtr);
     }
 
     static BakedOpState* directConstruct(LinearAllocator& allocator,
             const ClipRect* clip, const Rect& dstRect, const RecordedOp& recordedOp) {
-        return new (allocator) BakedOpState(clip, dstRect, recordedOp);
-    }
-
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
+        return allocator.create_trivial<BakedOpState>(clip, dstRect, recordedOp);
     }
 
     // computed state:
@@ -162,6 +158,8 @@
     const RecordedOp* op;
 
 private:
+    friend class LinearAllocator;
+
     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot,
             const RecordedOp& recordedOp, bool expandForStroke)
             : computedState(allocator, snapshot, recordedOp, expandForStroke)
diff --git a/libs/hwui/BufferPool.h b/libs/hwui/BufferPool.h
deleted file mode 100644
index 005b399..0000000
--- a/libs/hwui/BufferPool.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "utils/RefBase.h"
-#include "utils/Log.h"
-#include "utils/Macros.h"
-
-#include <atomic>
-#include <stdint.h>
-#include <memory>
-#include <mutex>
-
-namespace android {
-namespace uirenderer {
-
-/*
- * Simple thread-safe pool of int64_t arrays of a provided size.
- *
- * Permits allocating a client-provided max number of buffers.
- * If all buffers are in use, refuses to service any more
- * acquire requests until buffers are re-released to the pool.
- */
-class BufferPool : public VirtualLightRefBase {
-public:
-    class Buffer {
-        PREVENT_COPY_AND_ASSIGN(Buffer);
-    public:
-        int64_t* getBuffer() { return mBuffer.get(); }
-        size_t getSize() { return mSize; }
-
-        void release() {
-            LOG_ALWAYS_FATAL_IF(mPool.get() == nullptr, "attempt to release unacquired buffer");
-            mPool->release(this);
-        }
-
-        Buffer* incRef() {
-            mRefs++;
-            return this;
-        }
-
-        int decRef() {
-            int refs = mRefs.fetch_sub(1);
-            LOG_ALWAYS_FATAL_IF(refs == 0, "buffer reference decremented below 0");
-            return refs - 1;
-        }
-
-        bool isUniqueRef() {
-            return mRefs.load() == 1;
-        }
-
-    private:
-        friend class BufferPool;
-
-        Buffer(BufferPool* pool, size_t size) : mRefs(1) {
-            mSize = size;
-            mBuffer.reset(new int64_t[size]);
-            mPool = pool;
-        }
-
-        void setPool(BufferPool* pool) {
-            mPool = pool;
-        }
-
-        std::unique_ptr<Buffer> mNext;
-        std::unique_ptr<int64_t[]> mBuffer;
-        sp<BufferPool> mPool;
-        size_t mSize;
-
-        std::atomic_int mRefs;
-    };
-
-    BufferPool(size_t bufferSize, size_t count)
-            : mBufferSize(bufferSize), mCount(count) {}
-
-    /**
-     * Acquires a buffer from the buffer pool if available.
-     *
-     * Only `mCount` buffers are allowed to be in use at a single
-     * instance.
-     *
-     * If no buffer is available, i.e. `mCount` buffers are in use,
-     * returns nullptr.
-     *
-     * The pointer returned from this method *MUST NOT* be freed, instead
-     * BufferPool::release() must be called upon it when the client
-     * is done with it. Failing to release buffers will eventually make the
-     * BufferPool refuse to service any more BufferPool::acquire() requests.
-     */
-    BufferPool::Buffer* acquire() {
-        std::lock_guard<std::mutex> lock(mLock);
-
-        if (mHead.get() != nullptr) {
-            BufferPool::Buffer* res = mHead.release();
-            mHead = std::move(res->mNext);
-            res->mNext.reset(nullptr);
-            res->setPool(this);
-            res->incRef();
-            return res;
-        }
-
-        if (mAllocatedCount < mCount) {
-            ++mAllocatedCount;
-            return new BufferPool::Buffer(this, mBufferSize);
-        }
-
-        return nullptr;
-    }
-
-    /**
-     * Releases a buffer previously acquired by BufferPool::acquire().
-     *
-     * The released buffer is not valid after calling this method and
-     * attempting to use will result in undefined behavior.
-     */
-    void release(BufferPool::Buffer* buffer) {
-        std::lock_guard<std::mutex> lock(mLock);
-
-        if (buffer->decRef() != 0) {
-            return;
-        }
-
-        buffer->setPool(nullptr);
-
-        BufferPool::Buffer* list = mHead.get();
-        if (list == nullptr) {
-            mHead.reset(buffer);
-            mHead->mNext.reset(nullptr);
-            return;
-        }
-
-        while (list->mNext.get() != nullptr) {
-            list = list->mNext.get();
-        }
-
-        list->mNext.reset(buffer);
-    }
-
-    /*
-     * Used for testing.
-     */
-    size_t getAvailableBufferCount() {
-        size_t remainingToAllocateCount = mCount - mAllocatedCount;
-
-        BufferPool::Buffer* list = mHead.get();
-        if (list == nullptr) return remainingToAllocateCount;
-
-        int count = 1;
-        while (list->mNext.get() != nullptr) {
-            count++;
-            list = list->mNext.get();
-        }
-
-        return count + remainingToAllocateCount;
-    }
-
-private:
-    mutable std::mutex mLock;
-
-    size_t mBufferSize;
-    size_t mCount;
-    size_t mAllocatedCount = 0;
-    std::unique_ptr<BufferPool::Buffer> mHead;
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index 9c08b4d..e368537 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -361,17 +361,21 @@
             "expect RectangleList to be trivially destructible");
 
     if (mLastSerialization == nullptr) {
+        ClipBase* serialization = nullptr;
         switch (mMode) {
         case ClipMode::Rectangle:
-            mLastSerialization = allocator.create<ClipRect>(mClipRect);
+            serialization = allocator.create<ClipRect>(mClipRect);
             break;
         case ClipMode::RectangleList:
-            mLastSerialization = allocator.create<ClipRectList>(mRectangleList);
+            serialization = allocator.create<ClipRectList>(mRectangleList);
+            serialization->rect = mRectangleList.calculateBounds();
             break;
         case ClipMode::Region:
-            mLastSerialization = allocator.create<ClipRegion>(mClipRegion);
+            serialization = allocator.create<ClipRegion>(mClipRegion);
+            serialization->rect.set(mClipRegion.getBounds());
             break;
         }
+        mLastSerialization = serialization;
     }
     return mLastSerialization;
 }
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index c2e14a2..6d5833b 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -45,7 +45,7 @@
 };
 
 DamageAccumulator::DamageAccumulator() {
-    mHead = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
+    mHead = mAllocator.create_trivial<DirtyStack>();
     memset(mHead, 0, sizeof(DirtyStack));
     // Create a root that we will not pop off
     mHead->prev = mHead;
@@ -78,7 +78,7 @@
 
 void DamageAccumulator::pushCommon() {
     if (!mHead->next) {
-        DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
+        DirtyStack* nextFrame = mAllocator.create_trivial<DirtyStack>();
         nextFrame->next = nullptr;
         nextFrame->prev = mHead;
         mHead->next = nextFrame;
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 2d5979f..98ccf11 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -49,11 +49,6 @@
 
 class DeferredDisplayState {
 public:
-    static void* operator new(size_t size) = delete;
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
-    }
-
     // global op bounds, mapped by mMatrix to be in screen space coordinates, clipped
     Rect mBounds;
 
@@ -124,7 +119,7 @@
     DeferredDisplayList(const DeferredDisplayList& other); // disallow copy
 
     DeferredDisplayState* createState() {
-        return new (mAllocator) DeferredDisplayState();
+        return mAllocator.create_trivial<DeferredDisplayState>();
     }
 
     void tryRecycleState(DeferredDisplayState* state) {
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 3db14b5..00560d7 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -428,7 +428,7 @@
     if (!glyphs || count <= 0) return;
 
     int bytesCount = 2 * count;
-    DrawOp* op = new (alloc()) DrawTextOnPathOp(refText((const char*) glyphs, bytesCount),
+    DrawOp* op = new (alloc()) DrawTextOnPathOp(refBuffer<glyph_t>(glyphs, count),
             bytesCount, count, refPath(&path),
             hOffset, vOffset, refPaint(&paint));
     addDrawOp(op);
@@ -442,11 +442,10 @@
     if (!glyphs || count <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
 
     int bytesCount = count * 2;
-    const char* text = refText((const char*) glyphs, bytesCount);
     positions = refBuffer<float>(positions, count * 2);
     Rect bounds(boundsLeft, boundsTop, boundsRight, boundsBottom);
 
-    DrawOp* op = new (alloc()) DrawTextOp(text, bytesCount, count,
+    DrawOp* op = new (alloc()) DrawTextOp(refBuffer<glyph_t>(glyphs, count), bytesCount, count,
             x, y, positions, refPaint(&paint), totalAdvance, bounds);
     addDrawOp(op);
     drawTextDecorations(x, y, totalAdvance, paint);
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 06e72a0..a703e22 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -251,15 +251,11 @@
     inline const T* refBuffer(const T* srcBuffer, int32_t count) {
         if (!srcBuffer) return nullptr;
 
-        T* dstBuffer = (T*) mDisplayList->allocator.alloc(count * sizeof(T));
+        T* dstBuffer = (T*) mDisplayList->allocator.alloc<T>(count * sizeof(T));
         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
         return dstBuffer;
     }
 
-    inline char* refText(const char* text, size_t byteLength) {
-        return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
-    }
-
     inline const SkPath* refPath(const SkPath* path) {
         if (!path) return nullptr;
 
@@ -324,8 +320,7 @@
         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
-        SkBitmap* localBitmap = new (alloc()) SkBitmap(bitmap);
-        alloc().autoDestroy(localBitmap);
+        SkBitmap* localBitmap = alloc().create<SkBitmap>(bitmap);
         mDisplayList->bitmapResources.push_back(localBitmap);
         return localBitmap;
     }
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 92217edc..98315d0 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -64,7 +64,9 @@
     static void operator delete(void* ptr) { LOG_ALWAYS_FATAL("delete not supported"); }
     static void* operator new(size_t size) = delete; /** PURPOSELY OMITTED **/
     static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
+        // FIXME: Quick hack to keep old pipeline working, delete this when
+        // we no longer need to support HWUI_NEWOPS := false
+        return allocator.alloc<char>(size);
     }
 
     enum OpLogFlag {
@@ -1229,7 +1231,7 @@
 
 class DrawSomeTextOp : public DrawOp {
 public:
-    DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint)
+    DrawSomeTextOp(const glyph_t* text, int bytesCount, int count, const SkPaint* paint)
             : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
 
     virtual void output(int level, uint32_t logFlags) const override {
@@ -1251,14 +1253,14 @@
     }
 
 protected:
-    const char* mText;
+    const glyph_t* mText;
     int mBytesCount;
     int mCount;
 };
 
 class DrawTextOnPathOp : public DrawSomeTextOp {
 public:
-    DrawTextOnPathOp(const char* text, int bytesCount, int count,
+    DrawTextOnPathOp(const glyph_t* text, int bytesCount, int count,
             const SkPath* path, float hOffset, float vOffset, const SkPaint* paint)
             : DrawSomeTextOp(text, bytesCount, count, paint),
             mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
@@ -1280,7 +1282,7 @@
 
 class DrawTextOp : public DrawStrokableOp {
 public:
-    DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
+    DrawTextOp(const glyph_t* text, int bytesCount, int count, float x, float y,
             const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds)
             : DrawStrokableOp(bounds, paint), mText(text), mBytesCount(bytesCount), mCount(count),
             mX(x), mY(y), mPositions(positions), mTotalAdvance(totalAdvance) {
@@ -1341,7 +1343,7 @@
     virtual const char* name() override { return "DrawText"; }
 
 private:
-    const char* mText;
+    const glyph_t* mText;
     int mBytesCount;
     int mCount;
     float mX;
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 68bae6d..1b618c6 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -557,7 +557,7 @@
     mCurrentFont = Font::create(this, paint, matrix);
 }
 
-FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text,
+FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const glyph_t *glyphs,
         int numGlyphs, float radius, const float* positions) {
     checkInit();
 
@@ -577,7 +577,7 @@
     mBounds = nullptr;
 
     Rect bounds;
-    mCurrentFont->measure(paint, text, numGlyphs, &bounds, positions);
+    mCurrentFont->measure(paint, glyphs, numGlyphs, &bounds, positions);
 
     uint32_t intRadius = Blur::convertRadiusToInt(radius);
     uint32_t paddedWidth = (uint32_t) (bounds.right - bounds.left) + 2 * intRadius;
@@ -609,7 +609,7 @@
         // text has non-whitespace, so draw and blur to create the shadow
         // NOTE: bounds.isEmpty() can't be used here, since vertical coordinates are inverted
         // TODO: don't draw pure whitespace in the first place, and avoid needing this check
-        mCurrentFont->render(paint, text, numGlyphs, penX, penY,
+        mCurrentFont->render(paint, glyphs, numGlyphs, penX, penY,
                 Font::BITMAP, dataBuffer, paddedWidth, paddedHeight, nullptr, positions);
 
         // Unbind any PBO we might have used
@@ -643,17 +643,17 @@
     issueDrawCommand();
 }
 
-void FontRenderer::precache(const SkPaint* paint, const char* text, int numGlyphs,
+void FontRenderer::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
         const SkMatrix& matrix) {
     Font* font = Font::create(this, paint, matrix);
-    font->precache(paint, text, numGlyphs);
+    font->precache(paint, glyphs, numGlyphs);
 }
 
 void FontRenderer::endPrecaching() {
     checkTextureUpdate();
 }
 
-bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
+bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
         int numGlyphs, int x, int y, const float* positions,
         Rect* bounds, TextDrawFunctor* functor, bool forceFinish) {
     if (!mCurrentFont) {
@@ -662,7 +662,7 @@
     }
 
     initRender(clip, bounds, functor);
-    mCurrentFont->render(paint, text, numGlyphs, x, y, positions);
+    mCurrentFont->render(paint, glyphs, numGlyphs, x, y, positions);
 
     if (forceFinish) {
         finishRender();
@@ -671,7 +671,7 @@
     return mDrawn;
 }
 
-bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
         int numGlyphs, const SkPath* path, float hOffset, float vOffset,
         Rect* bounds, TextDrawFunctor* functor) {
     if (!mCurrentFont) {
@@ -680,7 +680,7 @@
     }
 
     initRender(clip, bounds, functor);
-    mCurrentFont->render(paint, text, numGlyphs, path, hOffset, vOffset);
+    mCurrentFont->render(paint, glyphs, numGlyphs, path, hOffset, vOffset);
     finishRender();
 
     return mDrawn;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 9994498..e10a81b 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -104,14 +104,14 @@
 
     void setFont(const SkPaint* paint, const SkMatrix& matrix);
 
-    void precache(const SkPaint* paint, const char* text, int numGlyphs, const SkMatrix& matrix);
+    void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkMatrix& matrix);
     void endPrecaching();
 
-    bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
+    bool renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
             int numGlyphs, int x, int y, const float* positions,
             Rect* outBounds, TextDrawFunctor* functor, bool forceFinish = true);
 
-    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
             int numGlyphs, const SkPath* path,
             float hOffset, float vOffset, Rect* outBounds, TextDrawFunctor* functor);
 
@@ -125,7 +125,7 @@
 
     // After renderDropShadow returns, the called owns the memory in DropShadow.image
     // and is responsible for releasing it when it's done with it
-    DropShadow renderDropShadow(const SkPaint* paint, const char *text, int numGlyphs,
+    DropShadow renderDropShadow(const SkPaint* paint, const glyph_t *glyphs, int numGlyphs,
             float radius, const float* positions);
 
     void setTextureFiltering(bool linearFiltering) {
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 185acce..4f51036 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -209,7 +209,7 @@
         // not rejected, so defer render as either Layer, or direct (possibly wrapped in saveLayer)
         if (node.getLayer()) {
             // HW layer
-            LayerOp* drawLayerOp = new (mAllocator) LayerOp(node);
+            LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(node);
             BakedOpState* bakedOpState = tryBakeOpState(*drawLayerOp);
             if (bakedOpState) {
                 // Node's layer already deferred, schedule it to render into parent layer
@@ -220,13 +220,13 @@
             // (temp layers are clipped to viewport, since they don't persist offscreen content)
             SkPaint saveLayerPaint;
             saveLayerPaint.setAlpha(properties.getAlpha());
-            deferBeginLayerOp(*new (mAllocator) BeginLayerOp(
+            deferBeginLayerOp(*mAllocator.create_trivial<BeginLayerOp>(
                     saveLayerBounds,
                     Matrix4::identity(),
                     nullptr, // no record-time clip - need only respect defer-time one
                     &saveLayerPaint));
             deferNodeOps(node);
-            deferEndLayerOp(*new (mAllocator) EndLayerOp());
+            deferEndLayerOp(*mAllocator.create_trivial<EndLayerOp>());
         } else {
             deferNodeOps(node);
         }
@@ -549,7 +549,7 @@
 void FrameBuilder::deferVectorDrawableOp(const VectorDrawableOp& op) {
     const SkBitmap& bitmap = op.vectorDrawable->getBitmapUpdateIfDirty();
     SkPaint* paint = op.vectorDrawable->getPaint();
-    const BitmapRectOp* resolvedOp = new (mAllocator) BitmapRectOp(op.unmappedBounds,
+    const BitmapRectOp* resolvedOp = mAllocator.create_trivial<BitmapRectOp>(op.unmappedBounds,
             op.localMatrix,
             op.localClip,
             paint,
@@ -565,7 +565,7 @@
     float y = *(op.y);
     float radius = *(op.radius);
     Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius);
-    const OvalOp* resolvedOp = new (mAllocator) OvalOp(
+    const OvalOp* resolvedOp = mAllocator.create_trivial<OvalOp>(
             unmappedBounds,
             op.localMatrix,
             op.localClip,
@@ -626,7 +626,7 @@
 void FrameBuilder::deferRoundRectPropsOp(const RoundRectPropsOp& op) {
     // allocate a temporary round rect op (with mAllocator, so it persists until render), so the
     // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
-    const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp(
+    const RoundRectOp* resolvedOp = mAllocator.create_trivial<RoundRectOp>(
             Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)),
             op.localMatrix,
             op.localClip,
@@ -754,7 +754,7 @@
 
     // record the draw operation into the previous layer's list of draw commands
     // uses state from the associated beginLayerOp, since it has all the state needed for drawing
-    LayerOp* drawLayerOp = new (mAllocator) LayerOp(
+    LayerOp* drawLayerOp = mAllocator.create_trivial<LayerOp>(
             beginLayerOp.unmappedBounds,
             beginLayerOp.localMatrix,
             beginLayerOp.localClip,
@@ -788,7 +788,7 @@
     /**
      * First, defer an operation to copy out the content from the rendertarget into a layer.
      */
-    auto copyToOp = new (mAllocator) CopyToLayerOp(op, layerHandle);
+    auto copyToOp = mAllocator.create_trivial<CopyToLayerOp>(op, layerHandle);
     BakedOpState* bakedState = BakedOpState::directConstruct(mAllocator,
             &(currentLayer().viewportClip), dstRect, *copyToOp);
     currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::CopyToLayer);
@@ -803,7 +803,7 @@
      * And stash an operation to copy that layer back under the rendertarget until
      * a balanced EndUnclippedLayerOp is seen
      */
-    auto copyFromOp = new (mAllocator) CopyFromLayerOp(op, layerHandle);
+    auto copyFromOp = mAllocator.create_trivial<CopyFromLayerOp>(op, layerHandle);
     bakedState = BakedOpState::directConstruct(mAllocator,
             &(currentLayer().viewportClip), dstRect, *copyFromOp);
     currentLayer().activeUnclippedSaveLayers.push_back(bakedState);
diff --git a/libs/hwui/FrameStatsObserver.h b/libs/hwui/FrameMetricsObserver.h
similarity index 85%
rename from libs/hwui/FrameStatsObserver.h
rename to libs/hwui/FrameMetricsObserver.h
index 7abc9f1..4f81c86 100644
--- a/libs/hwui/FrameStatsObserver.h
+++ b/libs/hwui/FrameMetricsObserver.h
@@ -18,14 +18,12 @@
 
 #include <utils/RefBase.h>
 
-#include "BufferPool.h"
-
 namespace android {
 namespace uirenderer {
 
-class FrameStatsObserver : public VirtualLightRefBase {
+class FrameMetricsObserver : public VirtualLightRefBase {
 public:
-    virtual void notify(BufferPool::Buffer* buffer);
+    virtual void notify(const int64_t* buffer);
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/FrameMetricsReporter.h b/libs/hwui/FrameMetricsReporter.h
new file mode 100644
index 0000000..c1cd0a92
--- /dev/null
+++ b/libs/hwui/FrameMetricsReporter.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/RefBase.h>
+#include <utils/Log.h>
+
+#include "FrameInfo.h"
+#include "FrameMetricsObserver.h"
+
+#include <string.h>
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+class FrameMetricsReporter {
+public:
+    FrameMetricsReporter() {}
+
+    void addObserver(FrameMetricsObserver* observer) {
+        mObservers.push_back(observer);
+    }
+
+    bool removeObserver(FrameMetricsObserver* observer) {
+        for (size_t i = 0; i < mObservers.size(); i++) {
+            if (mObservers[i].get() == observer) {
+                mObservers.erase(mObservers.begin() + i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    bool hasObservers() {
+        return mObservers.size() > 0;
+    }
+
+    void reportFrameMetrics(const int64_t* stats) {
+        for (size_t i = 0; i < mObservers.size(); i++) {
+            mObservers[i]->notify(stats);
+        }
+    }
+
+private:
+    std::vector< sp<FrameMetricsObserver> > mObservers;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
diff --git a/libs/hwui/FrameStatsReporter.h b/libs/hwui/FrameStatsReporter.h
deleted file mode 100644
index b8a9432..0000000
--- a/libs/hwui/FrameStatsReporter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <utils/RefBase.h>
-#include <utils/Log.h>
-
-#include "BufferPool.h"
-#include "FrameInfo.h"
-#include "FrameStatsObserver.h"
-
-#include <string.h>
-#include <vector>
-
-namespace android {
-namespace uirenderer {
-
-class FrameStatsReporter {
-public:
-    FrameStatsReporter() {
-        mBufferPool = new BufferPool(kBufferSize, kBufferCount);
-        LOG_ALWAYS_FATAL_IF(mBufferPool.get() == nullptr, "OOM: unable to allocate buffer pool");
-    }
-
-    void addObserver(FrameStatsObserver* observer) {
-        mObservers.push_back(observer);
-    }
-
-    bool removeObserver(FrameStatsObserver* observer) {
-        for (size_t i = 0; i < mObservers.size(); i++) {
-            if (mObservers[i].get() == observer) {
-                mObservers.erase(mObservers.begin() + i);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    bool hasObservers() {
-        return mObservers.size() > 0;
-    }
-
-    void reportFrameStats(const int64_t* stats) {
-        BufferPool::Buffer* statsBuffer = mBufferPool->acquire();
-
-        if (statsBuffer != nullptr) {
-            // copy in frame stats
-            memcpy(statsBuffer->getBuffer(), stats, kBufferSize * sizeof(*stats));
-
-            // notify on requested threads
-            for (size_t i = 0; i < mObservers.size(); i++) {
-                mObservers[i]->notify(statsBuffer);
-            }
-
-            // drop our reference
-            statsBuffer->release();
-        } else {
-            mDroppedReports++;
-        }
-    }
-
-    int getDroppedReports() { return mDroppedReports; }
-
-private:
-    static const size_t kBufferCount = 3;
-    static const size_t kBufferSize = static_cast<size_t>(FrameInfoIndex::NumIndexes);
-
-    std::vector< sp<FrameStatsObserver> > mObservers;
-
-    sp<BufferPool> mBufferPool;
-
-    int mDroppedReports = 0;
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 11293d6..c8f5e94 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -165,6 +165,10 @@
     generateTexture(colors, positions, info.width, 2, texture);
 
     mSize += size;
+    LOG_ALWAYS_FATAL_IF((int)size != texture->objectSize(),
+            "size != texture->objectSize(), size %" PRIu32 ", objectSize %d"
+            " width = %" PRIu32 " bytesPerPixel() = %zu",
+            size, texture->objectSize(), info.width, bytesPerPixel());
     mCache.put(gradient, texture);
 
     return texture;
diff --git a/libs/hwui/LayerBuilder.cpp b/libs/hwui/LayerBuilder.cpp
index 7170d4f..1ba3bf2 100644
--- a/libs/hwui/LayerBuilder.cpp
+++ b/libs/hwui/LayerBuilder.cpp
@@ -64,10 +64,6 @@
 
 class OpBatch : public BatchBase {
 public:
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
-    }
-
     OpBatch(batchid_t batchId, BakedOpState* op)
             : BatchBase(batchId, op, false) {
     }
@@ -80,10 +76,6 @@
 
 class MergingOpBatch : public BatchBase {
 public:
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
-    }
-
     MergingOpBatch(batchid_t batchId, BakedOpState* op)
             : BatchBase(batchId, op, true)
             , mClipSideFlags(op->computedState.clipSideFlags) {
@@ -247,7 +239,7 @@
         // put the verts in the frame allocator, since
         //     1) SimpleRectsOps needs verts, not rects
         //     2) even if mClearRects stored verts, std::vectors will move their contents
-        Vertex* const verts = (Vertex*) allocator.alloc(vertCount * sizeof(Vertex));
+        Vertex* const verts = (Vertex*) allocator.alloc<Vertex>(vertCount * sizeof(Vertex));
 
         Vertex* currentVert = verts;
         Rect bounds = mClearRects[0];
@@ -264,7 +256,7 @@
         // Flush all of these clears with a single draw
         SkPaint* paint = allocator.create<SkPaint>();
         paint->setXfermodeMode(SkXfermode::kClear_Mode);
-        SimpleRectsOp* op = new (allocator) SimpleRectsOp(bounds,
+        SimpleRectsOp* op = allocator.create_trivial<SimpleRectsOp>(bounds,
                 Matrix4::identity(), nullptr, paint,
                 verts, vertCount);
         BakedOpState* bakedState = BakedOpState::directConstruct(allocator,
@@ -292,7 +284,7 @@
         targetBatch->batchOp(op);
     } else  {
         // new non-merging batch
-        targetBatch = new (allocator) OpBatch(batchId, op);
+        targetBatch = allocator.create<OpBatch>(batchId, op);
         mBatchLookup[batchId] = targetBatch;
         mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch);
     }
@@ -323,7 +315,7 @@
         targetBatch->mergeOp(op);
     } else  {
         // new merging batch
-        targetBatch = new (allocator) MergingOpBatch(batchId, op);
+        targetBatch = allocator.create<MergingOpBatch>(batchId, op);
         mMergingBatchLookup[batchId].insert(std::make_pair(mergeId, targetBatch));
 
         mBatches.insert(mBatches.begin() + insertBatchIndex, targetBatch);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 587be92..b7a5923 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1949,7 +1949,7 @@
     }
 }
 
-void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text,
+void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const glyph_t* glyphs,
         int count, const float* positions,
         FontRenderer& fontRenderer, int alpha, float x, float y) {
     mCaches.textureState().activateTexture(0);
@@ -1963,7 +1963,7 @@
     //       if shader-based correction is enabled
     mCaches.dropShadowCache.setFontRenderer(fontRenderer);
     ShadowTexture* texture = mCaches.dropShadowCache.get(
-            paint, text, count, textShadow.radius, positions);
+            paint, glyphs, count, textShadow.radius, positions);
     // If the drop shadow exceeds the max texture size or couldn't be
     // allocated, skip drawing
     if (!texture) return;
@@ -2084,14 +2084,14 @@
     mState.setProjectionPathMask(allocator, path);
 }
 
-void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, float x, float y,
+void OpenGLRenderer::drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y,
         const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
         DrawOpMode drawOpMode) {
 
     if (drawOpMode == DrawOpMode::kImmediate) {
         // The checks for corner-case ignorable text and quick rejection is only done for immediate
         // drawing as ops from DeferredDisplayList are already filtered for these
-        if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) ||
+        if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint) ||
                 quickRejectSetupScissor(bounds)) {
             return;
         }
@@ -2115,7 +2115,7 @@
 
     if (CC_UNLIKELY(PaintUtils::hasTextShadow(paint))) {
         fontRenderer.setFont(paint, SkMatrix::I());
-        drawTextShadow(paint, text, count, positions, fontRenderer,
+        drawTextShadow(paint, glyphs, count, positions, fontRenderer,
                 alpha, oldX, oldY);
     }
 
@@ -2156,10 +2156,10 @@
     if (CC_UNLIKELY(paint->getTextAlign() != SkPaint::kLeft_Align)) {
         SkPaint paintCopy(*paint);
         paintCopy.setTextAlign(SkPaint::kLeft_Align);
-        status = fontRenderer.renderPosText(&paintCopy, clip, text, count, x, y,
+        status = fontRenderer.renderPosText(&paintCopy, clip, glyphs, count, x, y,
                 positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish);
     } else {
-        status = fontRenderer.renderPosText(paint, clip, text, count, x, y,
+        status = fontRenderer.renderPosText(paint, clip, glyphs, count, x, y,
                 positions, hasActiveLayer ? &layerBounds : nullptr, &functor, forceFinish);
     }
 
@@ -2173,9 +2173,9 @@
     mDirty = true;
 }
 
-void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+void OpenGLRenderer::drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count,
         const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
-    if (text == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) {
+    if (glyphs == nullptr || count == 0 || mState.currentlyIgnored() || canSkipText(paint)) {
         return;
     }
 
@@ -2198,7 +2198,7 @@
     const Rect* clip = &writableSnapshot()->getLocalClip();
     Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
-    if (fontRenderer.renderTextOnPath(paint, clip, text, count, path,
+    if (fontRenderer.renderTextOnPath(paint, clip, glyphs, count, path,
             hOffset, vOffset, hasLayer() ? &bounds : nullptr, &functor)) {
         dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, *currentTransform());
         mDirty = true;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 84bc9b0..dacd8cc 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -191,9 +191,9 @@
     void drawPath(const SkPath* path, const SkPaint* paint);
     void drawLines(const float* points, int count, const SkPaint* paint);
     void drawPoints(const float* points, int count, const SkPaint* paint);
-    void drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+    void drawTextOnPath(const glyph_t* glyphs, int bytesCount, int count, const SkPath* path,
             float hOffset, float vOffset, const SkPaint* paint);
-    void drawText(const char* text, int bytesCount, int count, float x, float y,
+    void drawText(const glyph_t* glyphs, int bytesCount, int count, float x, float y,
             const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = DrawOpMode::kImmediate);
     void drawRects(const float* rects, int count, const SkPaint* paint);
@@ -647,7 +647,7 @@
      * @param x The x coordinate where the shadow will be drawn
      * @param y The y coordinate where the shadow will be drawn
      */
-    void drawTextShadow(const SkPaint* paint, const char* text, int count,
+    void drawTextShadow(const SkPaint* paint, const glyph_t* glyphs, int count,
             const float* positions, FontRenderer& fontRenderer, int alpha,
             float x, float y);
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 3e11151..249b5b0 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -31,9 +31,6 @@
 // Compile-time properties
 ///////////////////////////////////////////////////////////////////////////////
 
-// If turned on, text is interpreted as glyphs instead of UTF-16
-#define RENDER_TEXT_AS_GLYPHS 1
-
 // Textures used by layers must have dimensions multiples of this number
 #define LAYER_SIZE 64
 
diff --git a/libs/hwui/PropertyValuesAnimatorSet.cpp b/libs/hwui/PropertyValuesAnimatorSet.cpp
index eca1afcc..b29f91f 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.cpp
+++ b/libs/hwui/PropertyValuesAnimatorSet.cpp
@@ -17,6 +17,8 @@
 #include "PropertyValuesAnimatorSet.h"
 #include "RenderNode.h"
 
+#include <algorithm>
+
 namespace android {
 namespace uirenderer {
 
@@ -53,16 +55,26 @@
 }
 
 void PropertyValuesAnimatorSet::onPlayTimeChanged(nsecs_t playTime) {
-    for (size_t i = 0; i < mAnimators.size(); i++) {
-        mAnimators[i]->setCurrentPlayTime(playTime);
+    if (playTime == 0 && mDuration > 0) {
+        // Reset all the animators
+        for (auto it = mAnimators.rbegin(); it != mAnimators.rend(); it++) {
+            // Note that this set may containing animators modifying the same property, so when we
+            // reset the animators, we need to make sure the animators that end the first will
+            // have the final say on what the property value should be.
+            (*it)->setFraction(0);
+        }
+    } else if (playTime >= mDuration) {
+        // Skip all the animators to end
+        for (auto& anim : mAnimators) {
+            anim->setFraction(1);
+        }
+    } else {
+        for (auto& anim : mAnimators) {
+            anim->setCurrentPlayTime(playTime);
+        }
     }
 }
 
-void PropertyValuesAnimatorSet::reset() {
-    // TODO: implement reset through adding a play state because we need to support reset() even
-    // during an animation run.
-}
-
 void PropertyValuesAnimatorSet::start(AnimationListener* listener) {
     init();
     mOneShotListener = listener;
@@ -70,20 +82,23 @@
 }
 
 void PropertyValuesAnimatorSet::reverse(AnimationListener* listener) {
-// TODO: implement reverse
+    init();
+    mOneShotListener = listener;
+    BaseRenderNodeAnimator::reverse();
 }
 
 void PropertyValuesAnimatorSet::init() {
     if (mInitialized) {
         return;
     }
-    nsecs_t maxDuration = 0;
-    for (size_t i = 0; i < mAnimators.size(); i++) {
-        if (maxDuration < mAnimators[i]->getTotalDuration()) {
-            maxDuration = mAnimators[i]->getTotalDuration();
-        }
-    }
-    mDuration = maxDuration;
+
+    // Sort the animators by their total duration. Note that all the animators in the set start at
+    // the same time, so the ones with longer total duration (which includes start delay) will
+    // be the ones that end later.
+    std::sort(mAnimators.begin(), mAnimators.end(), [](auto& a, auto&b) {
+        return a->getTotalDuration() < b->getTotalDuration();
+    });
+    mDuration = mAnimators[mAnimators.size() - 1]->getTotalDuration();
     mInitialized = true;
 }
 
@@ -106,18 +121,19 @@
 void PropertyAnimator::setCurrentPlayTime(nsecs_t playTime) {
     if (playTime >= mStartDelay && playTime < mTotalDuration) {
          nsecs_t currentIterationPlayTime = (playTime - mStartDelay) % mDuration;
-         mLatestFraction = currentIterationPlayTime / (float) mDuration;
+         float fraction = currentIterationPlayTime / (float) mDuration;
+         setFraction(fraction);
     } else if (mLatestFraction < 1.0f && playTime >= mTotalDuration) {
-        mLatestFraction = 1.0f;
-    } else {
-        return;
+        // This makes sure we only set the fraction = 1 once. It is needed because there might
+        // be another animator modifying the same property after this animator finishes, we need
+        // to make sure we don't set conflicting values on the same property within one frame.
+        setFraction(1.0f);
     }
-
-    setFraction(mLatestFraction);
 }
 
 void PropertyAnimator::setFraction(float fraction) {
-    float interpolatedFraction = mInterpolator->interpolate(mLatestFraction);
+    mLatestFraction = fraction;
+    float interpolatedFraction = mInterpolator->interpolate(fraction);
     mPropertyValuesHolder->setFraction(interpolatedFraction);
 }
 
diff --git a/libs/hwui/PropertyValuesAnimatorSet.h b/libs/hwui/PropertyValuesAnimatorSet.h
index 4c7ce52..c7ae7c0 100644
--- a/libs/hwui/PropertyValuesAnimatorSet.h
+++ b/libs/hwui/PropertyValuesAnimatorSet.h
@@ -50,7 +50,6 @@
 
     void start(AnimationListener* listener);
     void reverse(AnimationListener* listener);
-    void reset();
 
     void addPropertyAnimator(PropertyValuesHolder* propertyValuesHolder,
             Interpolator* interpolators, int64_t startDelays,
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 16929b8..269e590 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -83,9 +83,9 @@
 
 void RecordingCanvas::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {
     if (removed.flags & Snapshot::kFlagIsFboLayer) {
-        addOp(new (alloc()) EndLayerOp());
+        addOp(alloc().create_trivial<EndLayerOp>());
     } else if (removed.flags & Snapshot::kFlagIsLayer) {
-        addOp(new (alloc()) EndUnclippedLayerOp());
+        addOp(alloc().create_trivial<EndUnclippedLayerOp>());
     }
 }
 
@@ -167,7 +167,7 @@
         snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
         snapshot.roundRectClipState = nullptr;
 
-        addOp(new (alloc()) BeginLayerOp(
+        addOp(alloc().create_trivial<BeginLayerOp>(
                 unmappedBounds,
                 *previous.transform, // transform to *draw* with
                 previousClip, // clip to *draw* with
@@ -175,7 +175,7 @@
     } else {
         snapshot.flags |= Snapshot::kFlagIsLayer;
 
-        addOp(new (alloc()) BeginUnclippedLayerOp(
+        addOp(alloc().create_trivial<BeginUnclippedLayerOp>(
                 unmappedBounds,
                 *mState.currentSnapshot()->transform,
                 getRecordedClip(),
@@ -241,7 +241,7 @@
 }
 
 void RecordingCanvas::drawPaint(const SkPaint& paint) {
-    addOp(new (alloc()) RectOp(
+    addOp(alloc().create_trivial<RectOp>(
             mState.getRenderTargetClipBounds(), // OK, since we've not passed transform
             Matrix4::identity(),
             getRecordedClip(),
@@ -261,7 +261,7 @@
     if (floatCount < 2) return;
     floatCount &= ~0x1; // round down to nearest two
 
-    addOp(new (alloc()) PointsOp(
+    addOp(alloc().create_trivial<PointsOp>(
             calcBoundsOfPoints(points, floatCount),
             *mState.currentSnapshot()->transform,
             getRecordedClip(),
@@ -272,7 +272,7 @@
     if (floatCount < 4) return;
     floatCount &= ~0x3; // round down to nearest four
 
-    addOp(new (alloc()) LinesOp(
+    addOp(alloc().create_trivial<LinesOp>(
             calcBoundsOfPoints(points, floatCount),
             *mState.currentSnapshot()->transform,
             getRecordedClip(),
@@ -280,7 +280,7 @@
 }
 
 void RecordingCanvas::drawRect(float left, float top, float right, float bottom, const SkPaint& paint) {
-    addOp(new (alloc()) RectOp(
+    addOp(alloc().create_trivial<RectOp>(
             Rect(left, top, right, bottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -290,7 +290,7 @@
 void RecordingCanvas::drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint) {
     if (rects == nullptr) return;
 
-    Vertex* rectData = (Vertex*) mDisplayList->allocator.alloc(vertexCount * sizeof(Vertex));
+    Vertex* rectData = (Vertex*) mDisplayList->allocator.alloc<Vertex>(vertexCount * sizeof(Vertex));
     Vertex* vertex = rectData;
 
     float left = FLT_MAX;
@@ -313,7 +313,7 @@
         right = std::max(right, r);
         bottom = std::max(bottom, b);
     }
-    addOp(new (alloc()) SimpleRectsOp(
+    addOp(alloc().create_trivial<SimpleRectsOp>(
             Rect(left, top, right, bottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -347,7 +347,7 @@
 }
 void RecordingCanvas::drawRoundRect(float left, float top, float right, float bottom,
             float rx, float ry, const SkPaint& paint) {
-    addOp(new (alloc()) RoundRectOp(
+    addOp(alloc().create_trivial<RoundRectOp>(
             Rect(left, top, right, bottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -367,7 +367,7 @@
     mDisplayList->ref(ry);
     mDisplayList->ref(paint);
     refBitmapsInShader(paint->value.getShader());
-    addOp(new (alloc()) RoundRectPropsOp(
+    addOp(alloc().create_trivial<RoundRectPropsOp>(
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
             &paint->value,
@@ -389,7 +389,7 @@
     mDisplayList->ref(radius);
     mDisplayList->ref(paint);
     refBitmapsInShader(paint->value.getShader());
-    addOp(new (alloc()) CirclePropsOp(
+    addOp(alloc().create_trivial<CirclePropsOp>(
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
             &paint->value,
@@ -397,7 +397,7 @@
 }
 
 void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
-    addOp(new (alloc()) OvalOp(
+    addOp(alloc().create_trivial<OvalOp>(
             Rect(left, top, right, bottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -406,7 +406,7 @@
 
 void RecordingCanvas::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, const SkPaint& paint) {
-    addOp(new (alloc()) ArcOp(
+    addOp(alloc().create_trivial<ArcOp>(
             Rect(left, top, right, bottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -415,7 +415,7 @@
 }
 
 void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
-    addOp(new (alloc()) PathOp(
+    addOp(alloc().create_trivial<PathOp>(
             Rect(path.getBounds()),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -424,7 +424,7 @@
 
 void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
     mDisplayList->ref(tree);
-    addOp(new (alloc()) VectorDrawableOp(
+    addOp(alloc().create_trivial<VectorDrawableOp>(
             tree,
             Rect(tree->getBounds()),
             *(mState.currentSnapshot()->transform),
@@ -475,7 +475,7 @@
         drawBitmap(&bitmap, paint);
         restore();
     } else {
-        addOp(new (alloc()) BitmapRectOp(
+        addOp(alloc().create_trivial<BitmapRectOp>(
                 Rect(dstLeft, dstTop, dstRight, dstBottom),
                 *(mState.currentSnapshot()->transform),
                 getRecordedClip(),
@@ -487,7 +487,7 @@
 void RecordingCanvas::drawBitmapMesh(const SkBitmap& bitmap, int meshWidth, int meshHeight,
             const float* vertices, const int* colors, const SkPaint* paint) {
     int vertexCount = (meshWidth + 1) * (meshHeight + 1);
-    addOp(new (alloc()) BitmapMeshOp(
+    addOp(alloc().create_trivial<BitmapMeshOp>(
             calcBoundsOfPoints(vertices, vertexCount * 2),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -499,7 +499,7 @@
 void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_png_9patch& patch,
             float dstLeft, float dstTop, float dstRight, float dstBottom,
             const SkPaint* paint) {
-    addOp(new (alloc()) PatchOp(
+    addOp(alloc().create_trivial<PatchOp>(
             Rect(dstLeft, dstTop, dstRight, dstBottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -515,7 +515,7 @@
     positions = refBuffer<float>(positions, glyphCount * 2);
 
     // TODO: either must account for text shadow in bounds, or record separate ops for text shadows
-    addOp(new (alloc()) TextOp(
+    addOp(alloc().create_trivial<TextOp>(
             Rect(boundsLeft, boundsTop, boundsRight, boundsBottom),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -527,7 +527,7 @@
             float hOffset, float vOffset, const SkPaint& paint) {
     if (!glyphs || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
     glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
-    addOp(new (alloc()) TextOnPathOp(
+    addOp(alloc().create_trivial<TextOnPathOp>(
             mState.getLocalClipBounds(), // TODO: explicitly define bounds
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -535,7 +535,7 @@
 }
 
 void RecordingCanvas::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) {
-    addOp(new (alloc()) BitmapOp(
+    addOp(alloc().create_trivial<BitmapOp>(
             Rect(bitmap->width(), bitmap->height()),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -544,7 +544,7 @@
 
 void RecordingCanvas::drawRenderNode(RenderNode* renderNode) {
     auto&& stagingProps = renderNode->stagingProperties();
-    RenderNodeOp* op = new (alloc()) RenderNodeOp(
+    RenderNodeOp* op = alloc().create_trivial<RenderNodeOp>(
             Rect(stagingProps.getWidth(), stagingProps.getHeight()),
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
@@ -570,7 +570,7 @@
     Matrix4 totalTransform(*(mState.currentSnapshot()->transform));
     totalTransform.multiply(layer->getTransform());
 
-    addOp(new (alloc()) TextureLayerOp(
+    addOp(alloc().create_trivial<TextureLayerOp>(
             Rect(layer->getWidth(), layer->getHeight()),
             totalTransform,
             getRecordedClip(),
@@ -579,7 +579,7 @@
 
 void RecordingCanvas::callDrawGLFunction(Functor* functor) {
     mDisplayList->functors.push_back(functor);
-    addOp(new (alloc()) FunctorOp(
+    addOp(alloc().create_trivial<FunctorOp>(
             mState.getLocalClipBounds(), // TODO: explicitly define bounds
             *(mState.currentSnapshot()->transform),
             getRecordedClip(),
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index cc14e61..719872d 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -219,7 +219,7 @@
     inline const T* refBuffer(const T* srcBuffer, int32_t count) {
         if (!srcBuffer) return nullptr;
 
-        T* dstBuffer = (T*) mDisplayList->allocator.alloc(count * sizeof(T));
+        T* dstBuffer = (T*) mDisplayList->allocator.alloc<T>(count * sizeof(T));
         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
         return dstBuffer;
     }
@@ -290,8 +290,7 @@
         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
-        SkBitmap* localBitmap = new (alloc()) SkBitmap(bitmap);
-        alloc().autoDestroy(localBitmap);
+        SkBitmap* localBitmap = alloc().create<SkBitmap>(bitmap);
         mDisplayList->bitmapResources.push_back(localBitmap);
         return localBitmap;
     }
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index bade216..9ac76a4 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -218,6 +218,10 @@
     mAnimatorManager.addAnimator(animator);
 }
 
+void RenderNode::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
+    mAnimatorManager.removeAnimator(animator);
+}
+
 void RenderNode::damageSelf(TreeInfo& info) {
     if (isRenderable()) {
         if (properties().getClipDamageToBounds()) {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index f248de54..e037645 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -187,6 +187,12 @@
 
     // UI thread only!
     ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator);
+    void removeAnimator(const sp<BaseRenderNodeAnimator>& animator);
+
+    // This can only happen during pushStaging()
+    void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
+        mAnimatorManager.onAnimatorTargetChanged(animator);
+    }
 
     AnimatorManager& animators() { return mAnimatorManager; }
 
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index dbaa905..0ac2f14 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -46,7 +46,7 @@
 public:
     /** static void* operator new(size_t size); PURPOSELY OMITTED, allocator only **/
     static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
+        return allocator.alloc<RoundRectClipState>(size);
     }
 
     bool areaRequiresRoundRectClip(const Rect& rect) const {
@@ -67,7 +67,7 @@
 public:
     /** static void* operator new(size_t size); PURPOSELY OMITTED, allocator only **/
     static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc(size);
+        return allocator.alloc<ProjectionPathMask>(size);
     }
 
     const SkPath* projectionMask;
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index fe4b3d75..e1f0b2a 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -37,9 +37,9 @@
     hash = JenkinsHashMix(hash, flags);
     hash = JenkinsHashMix(hash, android::hash_type(italicStyle));
     hash = JenkinsHashMix(hash, android::hash_type(scaleX));
-    if (text) {
+    if (glyphs) {
         hash = JenkinsHashMixShorts(
-            hash, reinterpret_cast<const uint16_t*>(text), glyphCount);
+            hash, reinterpret_cast<const uint16_t*>(glyphs), glyphCount);
     }
     if (positions) {
         for (uint32_t i = 0; i < glyphCount * 2; i++) {
@@ -71,11 +71,11 @@
     if (lhs.scaleX < rhs.scaleX) return -1;
     if (lhs.scaleX > rhs.scaleX) return +1;
 
-    if (lhs.text != rhs.text) {
-        if (!lhs.text) return -1;
-        if (!rhs.text) return +1;
+    if (lhs.glyphs != rhs.glyphs) {
+        if (!lhs.glyphs) return -1;
+        if (!rhs.glyphs) return +1;
 
-        deltaInt = memcmp(lhs.text, rhs.text, lhs.glyphCount * sizeof(glyph_t));
+        deltaInt = memcmp(lhs.glyphs, rhs.glyphs, lhs.glyphCount * sizeof(glyph_t));
         if (deltaInt != 0) return deltaInt;
     }
 
@@ -145,7 +145,7 @@
     mCache.clear();
 }
 
-ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* glyphs, int numGlyphs,
+ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
         float radius, const float* positions) {
     ShadowText entry(paint, radius, numGlyphs, glyphs, positions);
     ShadowTexture* texture = mCache.get(entry);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index cf64788..d536c40 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -35,26 +35,21 @@
 
 struct ShadowText {
     ShadowText(): glyphCount(0), radius(0.0f), textSize(0.0f), typeface(nullptr),
-            flags(0), italicStyle(0.0f), scaleX(0), text(nullptr), positions(nullptr) {
+            flags(0), italicStyle(0.0f), scaleX(0), glyphs(nullptr), positions(nullptr) {
     }
 
     // len is the number of bytes in text
-    ShadowText(const SkPaint* paint, float radius, uint32_t glyphCount, const char* srcText,
-            const float* positions):
-            glyphCount(glyphCount), radius(radius), positions(positions) {
-        // TODO: Propagate this through the API, we should not cast here
-        text = (const char16_t*) srcText;
-
-        textSize = paint->getTextSize();
-        typeface = paint->getTypeface();
-
-        flags = 0;
-        if (paint->isFakeBoldText()) {
-            flags |= Font::kFakeBold;
-        }
-
-        italicStyle = paint->getTextSkewX();
-        scaleX = paint->getTextScaleX();
+    ShadowText(const SkPaint* paint, float radius, uint32_t glyphCount, const glyph_t* srcGlyphs,
+            const float* positions)
+            : glyphCount(glyphCount)
+            , radius(radius)
+            , textSize(paint->getTextSize())
+            , typeface(paint->getTypeface())
+            , flags(paint->isFakeBoldText() ? Font::kFakeBold : 0)
+            , italicStyle(paint->getTextSkewX())
+            , scaleX(paint->getTextScaleX())
+            , glyphs(srcGlyphs)
+            , positions(positions) {
     }
 
     ~ShadowText() {
@@ -73,8 +68,8 @@
     }
 
     void copyTextLocally() {
-        str.setTo((const char16_t*) text, glyphCount);
-        text = str.string();
+        str.setTo(reinterpret_cast<const char16_t*>(glyphs), glyphCount);
+        glyphs = reinterpret_cast<const glyph_t*>(str.string());
         if (positions != nullptr) {
             positionsCopy.clear();
             positionsCopy.appendArray(positions, glyphCount * 2);
@@ -89,7 +84,7 @@
     uint32_t flags;
     float italicStyle;
     float scaleX;
-    const char16_t* text;
+    const glyph_t* glyphs;
     const float* positions;
 
     // Not directly used to compute the cache key
@@ -135,7 +130,7 @@
      */
     void operator()(ShadowText& text, ShadowTexture*& texture) override;
 
-    ShadowTexture* get(const SkPaint* paint, const char* text,
+    ShadowTexture* get(const SkPaint* paint, const glyph_t* text,
             int numGlyphs, float radius, const float* positions);
 
     /**
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index c09b6dd..4f49a35 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -28,13 +28,19 @@
 
 static int bytesPerPixel(GLint glFormat) {
     switch (glFormat) {
+    // The wrapped-texture case, usually means a SurfaceTexture
+    case 0:
+        return 0;
     case GL_ALPHA:
         return 1;
     case GL_RGB:
         return 3;
     case GL_RGBA:
-    default:
         return 4;
+    case GL_RGBA16F:
+        return 16;
+    default:
+        LOG_ALWAYS_FATAL("UNKNOWN FORMAT %d", glFormat);
     }
 }
 
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 5510666..4dfb41d 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -23,7 +23,7 @@
 #include "Vertex.h"
 
 #include <GLES3/gl3.h>
-#include <SkScalerContext.h>
+#include <SkGlyph.h>
 #include <utils/Log.h>
 
 
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index dc82041..9a825fd 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -291,15 +291,15 @@
     return cachedGlyph;
 }
 
-void Font::render(const SkPaint* paint, const char *text,
+void Font::render(const SkPaint* paint, const glyph_t* glyphs,
             int numGlyphs, int x, int y, const float* positions) {
-    render(paint, text, numGlyphs, x, y, FRAMEBUFFER, nullptr,
+    render(paint, glyphs, numGlyphs, x, y, FRAMEBUFFER, nullptr,
             0, 0, nullptr, positions);
 }
 
-void Font::render(const SkPaint* paint, const char *text, int numGlyphs,
+void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
         const SkPath* path, float hOffset, float vOffset) {
-    if (numGlyphs == 0 || text == nullptr) {
+    if (numGlyphs == 0 || glyphs == nullptr) {
         return;
     }
 
@@ -315,7 +315,7 @@
     float pathLength = SkScalarToFloat(measure.getLength());
 
     if (paint->getTextAlign() != SkPaint::kLeft_Align) {
-        float textWidth = SkScalarToFloat(paint->measureText(text, numGlyphs * 2));
+        float textWidth = SkScalarToFloat(paint->measureText(glyphs, numGlyphs * 2));
         float pathOffset = pathLength;
         if (paint->getTextAlign() == SkPaint::kCenter_Align) {
             textWidth *= 0.5f;
@@ -325,7 +325,7 @@
     }
 
     while (glyphsCount < numGlyphs && penX < pathLength) {
-        glyph_t glyph = GET_GLYPH(text);
+        glyph_t glyph = *(glyphs++);
 
         if (IS_END_OF_STRING(glyph)) {
             break;
@@ -345,26 +345,26 @@
     }
 }
 
-void Font::measure(const SkPaint* paint, const char* text,
+void Font::measure(const SkPaint* paint, const glyph_t* glyphs,
         int numGlyphs, Rect *bounds, const float* positions) {
     if (bounds == nullptr) {
         ALOGE("No return rectangle provided to measure text");
         return;
     }
     bounds->set(1e6, -1e6, -1e6, 1e6);
-    render(paint, text, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions);
+    render(paint, glyphs, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions);
 }
 
-void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) {
+void Font::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs) {
     ATRACE_NAME("Precache Glyphs");
 
-    if (numGlyphs == 0 || text == nullptr) {
+    if (numGlyphs == 0 || glyphs == nullptr) {
         return;
     }
 
     int glyphsCount = 0;
     while (glyphsCount < numGlyphs) {
-        glyph_t glyph = GET_GLYPH(text);
+        glyph_t glyph = *(glyphs++);
 
         // Reached the end of the string
         if (IS_END_OF_STRING(glyph)) {
@@ -376,10 +376,10 @@
     }
 }
 
-void Font::render(const SkPaint* paint, const char* text,
+void Font::render(const SkPaint* paint, const glyph_t* glyphs,
         int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
         uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) {
-    if (numGlyphs == 0 || text == nullptr) {
+    if (numGlyphs == 0 || glyphs == nullptr) {
         return;
     }
 
@@ -396,7 +396,7 @@
     int glyphsCount = 0;
 
     while (glyphsCount < numGlyphs) {
-        glyph_t glyph = GET_GLYPH(text);
+        glyph_t glyph = *(glyphs++);
 
         // Reached the end of the string
         if (IS_END_OF_STRING(glyph)) {
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index 59518a1..288f733 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -23,7 +23,6 @@
 
 #include <SkScalar.h>
 #include <SkGlyphCache.h>
-#include <SkScalerContext.h>
 #include <SkPaint.h>
 #include <SkPathMeasure.h>
 
@@ -82,10 +81,10 @@
 
     ~Font();
 
-    void render(const SkPaint* paint, const char* text,
+    void render(const SkPaint* paint, const glyph_t* glyphs,
             int numGlyphs, int x, int y, const float* positions);
 
-    void render(const SkPaint* paint, const char* text,
+    void render(const SkPaint* paint, const glyph_t* glyphs,
             int numGlyphs, const SkPath* path, float hOffset, float vOffset);
 
     const Font::FontDescription& getDescription() const {
@@ -111,13 +110,13 @@
         MEASURE,
     };
 
-    void precache(const SkPaint* paint, const char* text, int numGlyphs);
+    void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs);
 
-    void render(const SkPaint* paint, const char *text,
+    void render(const SkPaint* paint, const glyph_t* glyphs,
             int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
             uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions);
 
-    void measure(const SkPaint* paint, const char* text,
+    void measure(const SkPaint* paint, const glyph_t* glyphs,
             int numGlyphs, Rect *bounds, const float* positions);
 
     void invalidateTextureCache(CacheTexture* cacheTexture = nullptr);
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
index 4e5debe..aa77d98 100644
--- a/libs/hwui/font/FontUtil.h
+++ b/libs/hwui/font/FontUtil.h
@@ -40,26 +40,9 @@
 
 #define CACHE_BLOCK_ROUNDING_SIZE 4
 
-#if RENDER_TEXT_AS_GLYPHS
-    typedef uint16_t glyph_t;
-    #define TO_GLYPH(g) g
-    #define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
-    #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text)
-    #define IS_END_OF_STRING(glyph) false
-
-    static inline glyph_t nextGlyph(const uint16_t** srcPtr) {
-        const uint16_t* src = *srcPtr;
-        glyph_t g = *src++;
-        *srcPtr = src;
-        return g;
-    }
-#else
-    typedef SkUnichar glyph_t;
-    #define TO_GLYPH(g) ((SkUnichar) g)
-    #define GET_METRICS(cache, glyph) cache->getUnicharMetrics(glyph)
-    #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text)
-    #define IS_END_OF_STRING(glyph) glyph < 0
-#endif
+typedef uint16_t glyph_t;
+#define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
+#define IS_END_OF_STRING(glyph) false
 
 #define AUTO_KERN(prev, next) (((next) - (prev) + 32) >> 6 << 16)
 
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
new file mode 100644
index 0000000..7d4ef0f
--- /dev/null
+++ b/libs/hwui/hwui_static_deps.mk
@@ -0,0 +1,28 @@
+###############################################################################
+#
+#
+# This file contains the shared and static dependencies needed by any target
+# that attempts to statically link HWUI (i.e. libhwui_static build target). This
+# file should be included by any target that lists libhwui_static as a
+# dependency.
+#
+# This is a workaround for the fact that the build system does not add these
+# transitive dependencies when it attempts to link libhwui_static into another
+# library.
+#
+###############################################################################
+
+LOCAL_SHARED_LIBRARIES += \
+    liblog \
+    libcutils \
+    libutils \
+    libEGL \
+    libGLESv2 \
+    libskia \
+    libui \
+    libgui \
+    libprotobuf-cpp-lite
+
+ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
+    LOCAL_SHARED_LIBRARIES += libRS libRScpp
+endif
\ No newline at end of file
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index ea702c0..4f528b1 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -507,8 +507,8 @@
 
     mJankTracker.addFrame(*mCurrentFrameInfo);
     mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
-    if (CC_UNLIKELY(mFrameStatsReporter.get() != nullptr)) {
-        mFrameStatsReporter->reportFrameStats(mCurrentFrameInfo->data());
+    if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
+        mFrameMetricsReporter->reportFrameMetrics(mCurrentFrameInfo->data());
     }
 
     GpuMemoryTracker::onFrameCompleted();
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 168166e..cb61e51 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -20,7 +20,7 @@
 #include "DamageAccumulator.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
-#include "FrameStatsReporter.h"
+#include "FrameMetricsReporter.h"
 #include "IContextFactory.h"
 #include "LayerUpdateQueue.h"
 #include "RenderNode.h"
@@ -142,31 +142,23 @@
         return mRenderThread.renderState();
     }
 
-    void addFrameStatsObserver(FrameStatsObserver* observer) {
-        if (mFrameStatsReporter.get() == nullptr) {
-            mFrameStatsReporter.reset(new FrameStatsReporter());
+    void addFrameMetricsObserver(FrameMetricsObserver* observer) {
+        if (mFrameMetricsReporter.get() == nullptr) {
+            mFrameMetricsReporter.reset(new FrameMetricsReporter());
         }
 
-        mFrameStatsReporter->addObserver(observer);
+        mFrameMetricsReporter->addObserver(observer);
     }
 
-    void removeFrameStatsObserver(FrameStatsObserver* observer) {
-        if (mFrameStatsReporter.get() != nullptr) {
-            mFrameStatsReporter->removeObserver(observer);
-            if (!mFrameStatsReporter->hasObservers()) {
-                mFrameStatsReporter.reset(nullptr);
+    void removeFrameMetricsObserver(FrameMetricsObserver* observer) {
+        if (mFrameMetricsReporter.get() != nullptr) {
+            mFrameMetricsReporter->removeObserver(observer);
+            if (!mFrameMetricsReporter->hasObservers()) {
+                mFrameMetricsReporter.reset(nullptr);
             }
         }
     }
 
-    long getDroppedFrameReportCount() {
-        if (mFrameStatsReporter.get() != nullptr) {
-            return mFrameStatsReporter->getDroppedReports();
-        }
-
-        return 0;
-    }
-
 private:
     friend class RegisterFrameCallbackTask;
     // TODO: Replace with something better for layer & other GL object
@@ -215,7 +207,7 @@
     std::string mName;
     JankTracker mJankTracker;
     FrameInfoVisualizer mProfiler;
-    std::unique_ptr<FrameStatsReporter> mFrameStatsReporter;
+    std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
 
     std::set<RenderNode*> mPrefetechedLayers;
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 7c6cd7e..04223a7 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -568,17 +568,17 @@
     post(task);
 }
 
-CREATE_BRIDGE2(addFrameStatsObserver, CanvasContext* context,
-        FrameStatsObserver* frameStatsObserver) {
-   args->context->addFrameStatsObserver(args->frameStatsObserver);
+CREATE_BRIDGE2(addFrameMetricsObserver, CanvasContext* context,
+        FrameMetricsObserver* frameStatsObserver) {
+   args->context->addFrameMetricsObserver(args->frameStatsObserver);
    if (args->frameStatsObserver != nullptr) {
        args->frameStatsObserver->decStrong(args->context);
    }
    return nullptr;
 }
 
-void RenderProxy::addFrameStatsObserver(FrameStatsObserver* observer) {
-    SETUP_TASK(addFrameStatsObserver);
+void RenderProxy::addFrameMetricsObserver(FrameMetricsObserver* observer) {
+    SETUP_TASK(addFrameMetricsObserver);
     args->context = mContext;
     args->frameStatsObserver = observer;
     if (observer != nullptr) {
@@ -587,17 +587,17 @@
     post(task);
 }
 
-CREATE_BRIDGE2(removeFrameStatsObserver, CanvasContext* context,
-        FrameStatsObserver* frameStatsObserver) {
-   args->context->removeFrameStatsObserver(args->frameStatsObserver);
+CREATE_BRIDGE2(removeFrameMetricsObserver, CanvasContext* context,
+        FrameMetricsObserver* frameStatsObserver) {
+   args->context->removeFrameMetricsObserver(args->frameStatsObserver);
    if (args->frameStatsObserver != nullptr) {
        args->frameStatsObserver->decStrong(args->context);
    }
    return nullptr;
 }
 
-void RenderProxy::removeFrameStatsObserver(FrameStatsObserver* observer) {
-    SETUP_TASK(removeFrameStatsObserver);
+void RenderProxy::removeFrameMetricsObserver(FrameMetricsObserver* observer) {
+    SETUP_TASK(removeFrameMetricsObserver);
     args->context = mContext;
     args->frameStatsObserver = observer;
     if (observer != nullptr) {
@@ -606,16 +606,6 @@
     post(task);
 }
 
-CREATE_BRIDGE1(getDroppedFrameReportCount, CanvasContext* context) {
-    return (void*) args->context->getDroppedFrameReportCount();
-}
-
-long RenderProxy::getDroppedFrameReportCount() {
-    SETUP_TASK(getDroppedFrameReportCount);
-    args->context = mContext;
-    return (long) postAndWait(task);
-}
-
 void RenderProxy::post(RenderTask* task) {
     mRenderThread.queue(task);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 178724a..8d65a82 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -29,7 +29,7 @@
 #include <utils/StrongPointer.h>
 
 #include "../Caches.h"
-#include "../FrameStatsObserver.h"
+#include "../FrameMetricsObserver.h"
 #include "../IContextFactory.h"
 #include "CanvasContext.h"
 #include "DrawFrameTask.h"
@@ -113,8 +113,8 @@
     ANDROID_API void drawRenderNode(RenderNode* node);
     ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom);
 
-    ANDROID_API void addFrameStatsObserver(FrameStatsObserver* observer);
-    ANDROID_API void removeFrameStatsObserver(FrameStatsObserver* observer);
+    ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
+    ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API long getDroppedFrameReportCount();
 
 private:
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 5ed7aa4..3440d03 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -58,27 +58,22 @@
     return layerUpdater;
 }
 
-void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
-        const SkPaint& paint, float x, float y) {
-    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
-    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
-            "must use glyph encoding");
+void TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text,
+        std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
+        float* outTotalAdvance, Rect* outBounds) {
+    Rect bounds;
+    float totalAdvance = 0;
     SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
     SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
-
-    float totalAdvance = 0;
-    std::vector<glyph_t> glyphs;
-    std::vector<float> positions;
-    Rect bounds;
     while (*text != '\0') {
         SkUnichar unichar = SkUTF8_NextUnichar(&text);
         glyph_t glyph = autoCache.getCache()->unicharToGlyph(unichar);
         autoCache.getCache()->unicharToGlyph(unichar);
 
         // push glyph and its relative position
-        glyphs.push_back(glyph);
-        positions.push_back(totalAdvance);
-        positions.push_back(0);
+        outGlyphs->push_back(glyph);
+        outPositions->push_back(totalAdvance);
+        outPositions->push_back(0);
 
         // compute bounds
         SkGlyph skGlyph = autoCache.getCache()->getUnicharMetrics(unichar);
@@ -91,6 +86,23 @@
         paint.getTextWidths(&glyph, sizeof(glyph), &skWidth, NULL);
         totalAdvance += skWidth;
     }
+    *outBounds = bounds;
+    *outTotalAdvance = totalAdvance;
+}
+
+void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
+        const SkPaint& paint, float x, float y) {
+    // drawing text requires GlyphID TextEncoding (which JNI layer would have done)
+    LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
+            "must use glyph encoding");
+    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
+    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
+
+    std::vector<glyph_t> glyphs;
+    std::vector<float> positions;
+    float totalAdvance;
+    Rect bounds;
+    layoutTextUnscaled(paint, text, &glyphs, &positions, &totalAdvance, &bounds);
 
     // apply alignment via x parameter (which JNI layer would have done)
     if (paint.getTextAlign() == SkPaint::kCenter_Align) {
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index ae08142..6f23705 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -205,6 +205,10 @@
 
     static SkColor interpolateColor(float fraction, SkColor start, SkColor end);
 
+    static void layoutTextUnscaled(const SkPaint& paint, const char* text,
+            std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
+            float* outTotalAdvance, Rect* outBounds);
+
     static void drawTextToCanvas(TestCanvas* canvas, const char* text,
             const SkPaint& paint, float x, float y);
 
diff --git a/libs/hwui/tests/microbench/TaskManagerBench.cpp b/libs/hwui/tests/microbench/TaskManagerBench.cpp
new file mode 100644
index 0000000..0ea30e47
--- /dev/null
+++ b/libs/hwui/tests/microbench/TaskManagerBench.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <benchmark/Benchmark.h>
+
+#include "thread/Task.h"
+#include "thread/TaskManager.h"
+#include "thread/TaskProcessor.h"
+#include "tests/microbench/MicroBench.h"
+
+#include <vector>
+
+using namespace android;
+using namespace android::uirenderer;
+
+class TrivialTask : public Task<char> {};
+
+class TrivialProcessor : public TaskProcessor<char> {
+public:
+    TrivialProcessor(TaskManager* manager)
+            : TaskProcessor(manager) {}
+    virtual ~TrivialProcessor() {}
+    virtual void onProcess(const sp<Task<char> >& task) override {
+        TrivialTask* t = static_cast<TrivialTask*>(task.get());
+        t->setResult(reinterpret_cast<intptr_t>(t) % 16 == 0 ? 'a' : 'b');
+    }
+};
+
+BENCHMARK_NO_ARG(BM_TaskManager_allocateTask);
+void BM_TaskManager_allocateTask::Run(int iters) {
+    std::vector<sp<TrivialTask> > tasks;
+    tasks.reserve(iters);
+
+    StartBenchmarkTiming();
+    for (int i = 0; i < iters; i++) {
+        tasks.emplace_back(new TrivialTask);
+        MicroBench::DoNotOptimize(tasks.back());
+    }
+    StopBenchmarkTiming();
+}
+
+BENCHMARK_NO_ARG(BM_TaskManager_enqueueTask);
+void BM_TaskManager_enqueueTask::Run(int iters) {
+    TaskManager taskManager;
+    sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
+    std::vector<sp<TrivialTask> > tasks;
+    tasks.reserve(iters);
+
+    StartBenchmarkTiming();
+    for (int i = 0; i < iters; i++) {
+        tasks.emplace_back(new TrivialTask);
+        MicroBench::DoNotOptimize(tasks.back());
+        processor->add(tasks.back());
+    }
+    StopBenchmarkTiming();
+
+    for (sp<TrivialTask>& task : tasks) {
+        task->getResult();
+    }
+}
+
+BENCHMARK_NO_ARG(BM_TaskManager_enqueueRunDeleteTask);
+void BM_TaskManager_enqueueRunDeleteTask::Run(int iters) {
+    TaskManager taskManager;
+    sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager));
+    std::vector<sp<TrivialTask> > tasks;
+    tasks.reserve(iters);
+
+    StartBenchmarkTiming();
+    for (int i = 0; i < iters; i++) {
+        tasks.emplace_back(new TrivialTask);
+        MicroBench::DoNotOptimize(tasks.back());
+        processor->add(tasks.back());
+    }
+    for (sp<TrivialTask>& task : tasks) {
+        MicroBench::DoNotOptimize(task->getResult());
+    }
+    tasks.clear();
+    StopBenchmarkTiming();
+}
diff --git a/libs/hwui/tests/unit/BufferPoolTests.cpp b/libs/hwui/tests/unit/BufferPoolTests.cpp
deleted file mode 100644
index 44e6d3a..0000000
--- a/libs/hwui/tests/unit/BufferPoolTests.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <BufferPool.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-namespace uirenderer {
-
-TEST(BufferPool, acquireThenRelease) {
-    static const int numRuns = 5;
-
-    // 10 buffers of size 1
-    static const size_t bufferSize = 1;
-    static const size_t bufferCount = 10;
-    sp<BufferPool> pool = new BufferPool(bufferSize, bufferCount);
-
-    for (int run = 0; run < numRuns; run++) {
-        BufferPool::Buffer* acquiredBuffers[bufferCount];
-        for (size_t i = 0; i < bufferCount; i++) {
-            ASSERT_EQ(bufferCount - i, pool->getAvailableBufferCount());
-            acquiredBuffers[i] = pool->acquire();
-            ASSERT_NE(nullptr, acquiredBuffers[i]);
-            ASSERT_TRUE(acquiredBuffers[i]->isUniqueRef());
-        }
-
-        for (size_t i = 0; i < bufferCount; i++) {
-            ASSERT_EQ(i, pool->getAvailableBufferCount());
-            acquiredBuffers[i]->release();
-            acquiredBuffers[i] = nullptr;
-        }
-
-        ASSERT_EQ(bufferCount, pool->getAvailableBufferCount());
-    }
-}
-
-TEST(BufferPool, acquireReleaseInterleaved) {
-    static const int numRuns = 5;
-
-    // 10 buffers of size 1
-    static const size_t bufferSize = 1;
-    static const size_t bufferCount = 10;
-
-    sp<BufferPool> pool = new BufferPool(bufferSize, bufferCount);
-
-    for (int run = 0; run < numRuns; run++) {
-        BufferPool::Buffer* acquiredBuffers[bufferCount];
-
-        // acquire all
-        for (size_t i = 0; i < bufferCount; i++) {
-            ASSERT_EQ(bufferCount - i, pool->getAvailableBufferCount());
-            acquiredBuffers[i] = pool->acquire();
-            ASSERT_NE(nullptr, acquiredBuffers[i]);
-        }
-
-        // release half
-        for (size_t i = 0; i < bufferCount / 2; i++) {
-            ASSERT_EQ(i, pool->getAvailableBufferCount());
-            acquiredBuffers[i]->release();
-            acquiredBuffers[i] = nullptr;
-        }
-
-        const size_t expectedRemaining = bufferCount / 2;
-        ASSERT_EQ(expectedRemaining, pool->getAvailableBufferCount());
-
-        // acquire half
-        for (size_t i = 0; i < bufferCount / 2; i++) {
-            ASSERT_EQ(expectedRemaining - i, pool->getAvailableBufferCount());
-            acquiredBuffers[i] = pool->acquire();
-        }
-
-        // acquire one more, should fail
-        ASSERT_EQ(nullptr, pool->acquire());
-
-        // release all
-        for (size_t i = 0; i < bufferCount; i++) {
-            ASSERT_EQ(i, pool->getAvailableBufferCount());
-            acquiredBuffers[i]->release();
-            acquiredBuffers[i] = nullptr;
-        }
-
-        ASSERT_EQ(bufferCount, pool->getAvailableBufferCount());
-    }
-}
-
-};
-};
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
index 4cae737..679569e 100644
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ b/libs/hwui/tests/unit/ClipAreaTests.cpp
@@ -133,7 +133,7 @@
         ASSERT_NE(nullptr, serializedClip);
         ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode);
         auto clipRect = reinterpret_cast<const ClipRect*>(serializedClip);
-        ASSERT_EQ(Rect(200, 200), clipRect->rect);
+        EXPECT_EQ(Rect(200, 200), clipRect->rect);
         EXPECT_EQ(serializedClip, area.serializeClip(allocator))
                 << "Requery of clip on unmodified ClipArea must return same pointer.";
     }
@@ -147,7 +147,10 @@
         ASSERT_NE(nullptr, serializedClip);
         ASSERT_EQ(ClipMode::RectangleList, serializedClip->mode);
         auto clipRectList = reinterpret_cast<const ClipRectList*>(serializedClip);
-        ASSERT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount());
+        EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount());
+        EXPECT_FALSE(clipRectList->rect.isEmpty());
+        EXPECT_FLOAT_EQ(199.87817f, clipRectList->rect.right)
+            << "Right side should be clipped by rotated rect";
         EXPECT_EQ(serializedClip, area.serializeClip(allocator))
                 << "Requery of clip on unmodified ClipArea must return same pointer.";
     }
@@ -161,8 +164,9 @@
         ASSERT_NE(nullptr, serializedClip);
         ASSERT_EQ(ClipMode::Region, serializedClip->mode);
         auto clipRegion = reinterpret_cast<const ClipRegion*>(serializedClip);
-        ASSERT_EQ(SkIRect::MakeWH(200, 200), clipRegion->region.getBounds())
+        EXPECT_EQ(SkIRect::MakeWH(200, 200), clipRegion->region.getBounds())
                 << "Clip region should be 200x200";
+        EXPECT_EQ(Rect(200, 200), clipRegion->rect);
         EXPECT_EQ(serializedClip, area.serializeClip(allocator))
                 << "Requery of clip on unmodified ClipArea must return same pointer.";
     }
diff --git a/libs/hwui/tests/unit/LinearAllocatorTests.cpp b/libs/hwui/tests/unit/LinearAllocatorTests.cpp
index 5c44290..402a09c 100644
--- a/libs/hwui/tests/unit/LinearAllocatorTests.cpp
+++ b/libs/hwui/tests/unit/LinearAllocatorTests.cpp
@@ -30,7 +30,7 @@
 TEST(LinearAllocator, create) {
     LinearAllocator la;
     EXPECT_EQ(0u, la.usedSize());
-    la.alloc(64);
+    la.alloc<char>(64);
     // There's some internal tracking as well as padding
     // so the usedSize isn't strictly defined
     EXPECT_LE(64u, la.usedSize());
@@ -50,13 +50,12 @@
             la.create<TestUtils::SignalingDtor>()->setSignal(destroyed + i);
             la.create<SimplePair>();
         }
-        la.alloc(100);
+        la.alloc<char>(100);
         for (int i = 0; i < 5; i++) {
-            auto sd = new (la) TestUtils::SignalingDtor(destroyed + 5 + i);
-            la.autoDestroy(sd);
-            new (la) SimplePair();
+            la.create<TestUtils::SignalingDtor>(destroyed + 5 + i);
+            la.create_trivial<SimplePair>();
         }
-        la.alloc(100);
+        la.alloc<char>(100);
         for (int i = 0; i < 10; i++) {
             EXPECT_EQ(0, destroyed[i]);
         }
@@ -70,7 +69,7 @@
     int destroyed = 0;
     {
         LinearAllocator la;
-        auto addr = la.alloc(100);
+        auto addr = la.alloc<char>(100);
         EXPECT_LE(100u, la.usedSize());
         la.rewindIfLastAlloc(addr, 100);
         EXPECT_GT(16u, la.usedSize());
diff --git a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
index c54f2c3..0d26df2 100644
--- a/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextDropShadowCacheTests.cpp
@@ -21,29 +21,31 @@
 #include "utils/Blur.h"
 #include "tests/common/TestUtils.h"
 
-#include <SkBlurDrawLooper.h>
 #include <SkPaint.h>
 
 using namespace android;
 using namespace android::uirenderer;
 
 RENDERTHREAD_TEST(TextDropShadowCache, addRemove) {
+    SkPaint paint;
+    paint.setTextSize(20);
+
     GammaFontRenderer gammaFontRenderer;
     FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer();
-    TextDropShadowCache cache(5000);
+    fontRenderer.setFont(&paint, SkMatrix::I());
+    TextDropShadowCache cache(MB(5));
     cache.setFontRenderer(fontRenderer);
 
-    SkPaint paint;
-    paint.setLooper(SkBlurDrawLooper::Create((SkColor)0xFFFFFFFF,
-            Blur::convertRadiusToSigma(10), 10, 10))->unref();
-    std::string msg("This is a test");
-    std::unique_ptr<float[]> positions(new float[msg.length()]);
-    for (size_t i = 0; i < msg.length(); i++) {
-        positions[i] = i * 10.0f;
-    }
-    fontRenderer.setFont(&paint, SkMatrix::I());
-    ShadowTexture* texture = cache.get(&paint, msg.c_str(), msg.length(),
-            10.0f, positions.get());
+    std::vector<glyph_t> glyphs;
+    std::vector<float> positions;
+    float totalAdvance;
+    uirenderer::Rect bounds;
+    TestUtils::layoutTextUnscaled(paint, "This is a test",
+            &glyphs, &positions, &totalAdvance, &bounds);
+    EXPECT_TRUE(bounds.contains(5, -10, 100, 0)) << "Expect input to be nontrivially sized";
+
+    ShadowTexture* texture = cache.get(&paint, glyphs.data(), glyphs.size(), 10, positions.data());
+
     ASSERT_TRUE(texture);
     ASSERT_FALSE(texture->cleanup);
     ASSERT_EQ((uint32_t) texture->objectSize(), cache.getSize());
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index a07845e..d346b85 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -103,7 +103,7 @@
     return true;
 }
 
-bool TaskManager::WorkerThread::addTask(TaskWrapper task) {
+bool TaskManager::WorkerThread::addTask(const TaskWrapper& task) {
     if (!isRunning()) {
         run(mName.string(), PRIORITY_DEFAULT);
     } else if (exitPending()) {
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index d0eb304..e4808f7 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -80,7 +80,7 @@
     public:
         WorkerThread(const String8 name): mSignal(Condition::WAKE_UP_ONE), mName(name) { }
 
-        bool addTask(TaskWrapper task);
+        bool addTask(const TaskWrapper& task);
         size_t getTaskCount() const;
         void exit();
 
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index e6a4c03..5bba420 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -81,10 +81,6 @@
 
 #define min(x,y) (((x) < (y)) ? (x) : (y))
 
-void* operator new(std::size_t size, android::uirenderer::LinearAllocator& la) {
-    return la.alloc(size);
-}
-
 namespace android {
 namespace uirenderer {
 
@@ -171,7 +167,7 @@
     mNext = start(mCurrentPage);
 }
 
-void* LinearAllocator::alloc(size_t size) {
+void* LinearAllocator::allocImpl(size_t size) {
     size = ALIGN(size);
     if (size > mMaxAllocSize && !fitsInCurrentPage(size)) {
         ALOGV("Exceeded max size %zu > %zu", size, mMaxAllocSize);
@@ -196,7 +192,7 @@
                   "DestructorNode must have standard layout");
     static_assert(std::is_trivially_destructible<DestructorNode>::value,
                   "DestructorNode must be trivially destructable");
-    auto node = new (*this) DestructorNode();
+    auto node = new (allocImpl(sizeof(DestructorNode))) DestructorNode();
     node->dtor = dtor;
     node->addr = addr;
     node->next = mDtorList;
diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h
index dcbc0dd..0a0e185 100644
--- a/libs/hwui/utils/LinearAllocator.h
+++ b/libs/hwui/utils/LinearAllocator.h
@@ -52,30 +52,36 @@
      * The lifetime of the returned buffers is tied to that of the LinearAllocator. If calling
      * delete() on an object stored in a buffer is needed, it should be overridden to use
      * rewindIfLastAlloc()
+     *
+     * Note that unlike create, for alloc the type is purely for compile-time error
+     * checking and does not affect size.
      */
-    void* alloc(size_t size);
+    template<class T>
+    void* alloc(size_t size) {
+        static_assert(std::is_trivially_destructible<T>::value,
+                "Error, type is non-trivial! did you mean to use create()?");
+        return allocImpl(size);
+    }
 
     /**
      * Allocates an instance of the template type with the given construction parameters
      * and adds it to the automatic destruction list.
      */
     template<class T, typename... Params>
-    T* create(Params... params) {
-        T* ret = new (*this) T(params...);
-        autoDestroy(ret);
+    T* create(Params&&... params) {
+        T* ret = new (allocImpl(sizeof(T))) T(std::forward<Params>(params)...);
+        if (!std::is_trivially_destructible<T>::value) {
+            auto dtor = [](void* ret) { ((T*)ret)->~T(); };
+            addToDestructionList(dtor, ret);
+        }
         return ret;
     }
 
-    /**
-     * Adds the pointer to the tracking list to have its destructor called
-     * when the LinearAllocator is destroyed.
-     */
-    template<class T>
-    void autoDestroy(T* addr) {
-        if (!std::is_trivially_destructible<T>::value) {
-            auto dtor = [](void* addr) { ((T*)addr)->~T(); };
-            addToDestructionList(dtor, addr);
-        }
+    template<class T, typename... Params>
+    T* create_trivial(Params&&... params) {
+        static_assert(std::is_trivially_destructible<T>::value,
+                "Error, called create_trivial on a non-trivial type");
+        return new (allocImpl(sizeof(T))) T(std::forward<Params>(params)...);
     }
 
     /**
@@ -114,6 +120,8 @@
         DestructorNode* next = nullptr;
     };
 
+    void* allocImpl(size_t size);
+
     void addToDestructionList(Destructor, void* addr);
     void runDestructorFor(void* addr);
     Page* newPage(size_t pageSize);
@@ -159,7 +167,7 @@
             : linearAllocator(other.linearAllocator) {}
 
     T* allocate(size_t num, const void* = 0) {
-        return (T*)(linearAllocator.alloc(num * sizeof(T)));
+        return (T*)(linearAllocator.alloc<void*>(num * sizeof(T)));
     }
 
     void deallocate(pointer p, size_t num) {
@@ -187,6 +195,4 @@
 }; // namespace uirenderer
 }; // namespace android
 
-void* operator new(std::size_t size, android::uirenderer::LinearAllocator& la);
-
 #endif // ANDROID_LINEARALLOCATOR_H
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index d8f507c..a490685 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -28,7 +28,7 @@
  */
 public final class GnssMeasurement implements Parcelable {
     private int mFlags;
-    private byte mPrn;
+    private short mSvid;
     private double mTimeOffsetInNs;
     private short mState;
     private long mReceivedGpsTowInNs;
@@ -198,7 +198,7 @@
      */
     public void set(GnssMeasurement measurement) {
         mFlags = measurement.mFlags;
-        mPrn = measurement.mPrn;
+        mSvid = measurement.mSvid;
         mTimeOffsetInNs = measurement.mTimeOffsetInNs;
         mState = measurement.mState;
         mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
@@ -248,15 +248,15 @@
      * Gets the Pseudo-random number (PRN).
      * Range: [1, 32]
      */
-    public byte getPrn() {
-        return mPrn;
+    public short getSvid() {
+        return mSvid;
     }
 
     /**
      * Sets the Pseud-random number (PRN).
      */
-    public void setPrn(byte value) {
-        mPrn = value;
+    public void setSvid(short value) {
+        mSvid = value;
     }
 
     /**
@@ -1210,7 +1210,7 @@
             GnssMeasurement gnssMeasurement = new GnssMeasurement();
 
             gnssMeasurement.mFlags = parcel.readInt();
-            gnssMeasurement.mPrn = parcel.readByte();
+            gnssMeasurement.mSvid = (short) parcel.readInt();
             gnssMeasurement.mTimeOffsetInNs = parcel.readDouble();
             gnssMeasurement.mState = (short) parcel.readInt();
             gnssMeasurement.mReceivedGpsTowInNs = parcel.readLong();
@@ -1253,9 +1253,10 @@
         }
     };
 
+    @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mFlags);
-        parcel.writeByte(mPrn);
+        parcel.writeInt(mSvid);
         parcel.writeDouble(mTimeOffsetInNs);
         parcel.writeInt(mState);
         parcel.writeLong(mReceivedGpsTowInNs);
@@ -1301,7 +1302,7 @@
         final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
         StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
 
-        builder.append(String.format(format, "Prn", mPrn));
+        builder.append(String.format(format, "Svid", mSvid));
 
         builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
 
@@ -1422,7 +1423,7 @@
 
     private void initialize() {
         mFlags = HAS_NO_FLAGS;
-        setPrn(Byte.MIN_VALUE);
+        setSvid((short) 0);
         setTimeOffsetInNs(Long.MIN_VALUE);
         setState(STATE_UNKNOWN);
         setReceivedGpsTowInNs(Long.MIN_VALUE);
diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java
index 0e011d5..86328eb 100644
--- a/location/java/android/location/GnssNavigationMessage.java
+++ b/location/java/android/location/GnssNavigationMessage.java
@@ -26,7 +26,7 @@
 import java.security.InvalidParameterException;
 
 /**
- * A class containing a GPS satellite Navigation Message.
+ * A class containing a GNSS satellite Navigation Message.
  */
 public final class GnssNavigationMessage implements Parcelable {
 
@@ -84,7 +84,7 @@
     // End enumerations in sync with gps.h
 
     private byte mType;
-    private byte mPrn;
+    private short mSvid;
     private short mMessageId;
     private short mSubmessageId;
     private byte[] mData;
@@ -99,7 +99,7 @@
      */
     public void set(GnssNavigationMessage navigationMessage) {
         mType = navigationMessage.mType;
-        mPrn = navigationMessage.mPrn;
+        mSvid = navigationMessage.mSvid;
         mMessageId = navigationMessage.mMessageId;
         mSubmessageId = navigationMessage.mSubmessageId;
         mData = navigationMessage.mData;
@@ -153,15 +153,15 @@
      * Gets the Pseudo-random number.
      * Range: [1, 32].
      */
-    public byte getPrn() {
-        return mPrn;
+    public short getSvid() {
+        return mSvid;
     }
 
     /**
      * Sets the Pseud-random number.
      */
-    public void setPrn(byte value) {
-        mPrn = value;
+    public void setSvid(short value) {
+        mSvid = value;
     }
 
     /**
@@ -256,7 +256,7 @@
             GnssNavigationMessage navigationMessage = new GnssNavigationMessage();
 
             navigationMessage.setType(parcel.readByte());
-            navigationMessage.setPrn(parcel.readByte());
+            navigationMessage.setSvid((short) parcel.readInt());
             navigationMessage.setMessageId((short) parcel.readInt());
             navigationMessage.setSubmessageId((short) parcel.readInt());
 
@@ -281,9 +281,10 @@
         }
     };
 
+    @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeByte(mType);
-        parcel.writeByte(mPrn);
+        parcel.writeInt(mSvid);
         parcel.writeInt(mMessageId);
         parcel.writeInt(mSubmessageId);
         parcel.writeInt(mData.length);
@@ -302,7 +303,7 @@
         StringBuilder builder = new StringBuilder("GnssNavigationMessage:\n");
 
         builder.append(String.format(format, "Type", getTypeString()));
-        builder.append(String.format(format, "Prn", mPrn));
+        builder.append(String.format(format, "Svid", mSvid));
         builder.append(String.format(format, "Status", getStatusString()));
         builder.append(String.format(format, "MessageId", mMessageId));
         builder.append(String.format(format, "SubmessageId", mSubmessageId));
@@ -321,7 +322,7 @@
 
     private void initialize() {
         mType = MESSAGE_TYPE_UNKNOWN;
-        mPrn = 0;
+        mSvid = 0;
         mMessageId = -1;
         mSubmessageId = -1;
         mData = EMPTY_ARRAY;
diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java
index 77e8a5b..906e944 100644
--- a/location/java/android/location/GnssStatus.java
+++ b/location/java/android/location/GnssStatus.java
@@ -47,24 +47,26 @@
     public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2);
 
     /** @hide */
-    public static final int PRN_SHIFT_WIDTH = 3;
+    public static final int SVID_SHIFT_WIDTH = 7;
+    /** @hide */
+    public static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 3;
+    /** @hide */
+    public static final int CONSTELLATION_TYPE_MASK = 0xf;
 
     /* These package private values are modified by the LocationManager class */
-    /* package */ int[] mPrnWithFlags;
+    /* package */ int[] mSvidWithFlags;
     /* package */ float[] mSnrs;
     /* package */ float[] mElevations;
     /* package */ float[] mAzimuths;
-    /* package */ int[] mConstellationTypes;
     /* package */ int mSvCount;
 
-    GnssStatus(int svCount, int[] prnWithFlags, float[] snrs, float[] elevations, float[] azimuths,
-            int[] constellationTypes) {
+    GnssStatus(int svCount, int[] svidWithFlags, float[] snrs, float[] elevations,
+            float[] azimuths) {
         mSvCount = svCount;
-        mPrnWithFlags = prnWithFlags;
+        mSvidWithFlags = svidWithFlags;
         mSnrs = snrs;
         mElevations = elevations;
         mAzimuths = azimuths;
-        mConstellationTypes = constellationTypes;
     }
 
     /**
@@ -79,15 +81,16 @@
      * @param satIndex the index of the satellite in the list.
      */
     public int getConstellationType(int satIndex) {
-        return mConstellationTypes[satIndex];
+        return (mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
+                & CONSTELLATION_TYPE_MASK;
     }
 
     /**
      * Retrieves the pseudo-random number of the satellite at the specified position.
      * @param satIndex the index of the satellite in the list.
      */
-    public int getPrn(int satIndex) {
-        return mPrnWithFlags[satIndex] >> PRN_SHIFT_WIDTH;
+    public int getSvid(int satIndex) {
+        return mSvidWithFlags[satIndex] >> SVID_SHIFT_WIDTH;
     }
 
     /**
@@ -119,7 +122,7 @@
      * @param satIndex the index of the satellite in the list.
      */
     public boolean hasEphemeris(int satIndex) {
-        return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
     }
 
     /**
@@ -127,7 +130,7 @@
      * @param satIndex the index of the satellite in the list.
      */
     public boolean hasAlmanac(int satIndex) {
-        return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
+        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
     }
 
     /**
@@ -135,6 +138,6 @@
      * @param satIndex the index of the satellite in the list.
      */
     public boolean usedInFix(int satIndex) {
-        return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
+        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
     }
 }
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 8d2f781..e41e20c 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -138,15 +138,19 @@
     // For API-compat a public ctor() is not available
     GpsStatus() {}
 
-    private void setStatus(int svCount, int[] prnWithFlags, float[] snrs, float[] elevations,
-            float[] azimuths, int[] constellationTypes) { 
+    private void setStatus(int svCount, int[] svidWithFlags, float[] snrs, float[] elevations,
+            float[] azimuths) {
         clearSatellites();
         for (int i = 0; i < svCount; i++) {
+            final int constellationType =
+                    (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
+                    & GnssStatus.CONSTELLATION_TYPE_MASK;
             // Skip all non-GPS satellites.
-            if (constellationTypes[i] != GnssStatus.CONSTELLATION_GPS) {
+            if (constellationType != GnssStatus.CONSTELLATION_GPS) {
+                // TODO: translate the defacto pre-N use of  prn's >32 to new struct
                 continue;
             }
-            int prn = prnWithFlags[i] >> GnssStatus.PRN_SHIFT_WIDTH;
+            int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH;
             if (prn > 0 && prn <= NUM_SATELLITES) {
                 GpsSatellite satellite = mSatellites.get(prn);
                 if (satellite == null) {
@@ -159,11 +163,11 @@
                 satellite.mElevation = elevations[i];
                 satellite.mAzimuth = azimuths[i];
                 satellite.mHasEphemeris =
-                        (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
                 satellite.mHasAlmanac =
-                        (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
+                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
                 satellite.mUsedInFix =
-                        (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0;
+                        (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0;
             }
         }
     }
@@ -176,8 +180,8 @@
      */
     void setStatus(GnssStatus status, int timeToFirstFix) {
         mTimeToFirstFix = timeToFirstFix;
-        setStatus(status.mSvCount, status.mPrnWithFlags, status.mSnrs, status.mElevations,
-                status.mAzimuths, status.mConstellationTypes);
+        setStatus(status.mSvCount, status.mSvidWithFlags, status.mSnrs, status.mElevations,
+                status.mAzimuths);
     }
 
     void setTimeToFirstFix(int ttff) {
diff --git a/location/java/android/location/IGnssStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl
index d1c6a85..8c7d06e 100644
--- a/location/java/android/location/IGnssStatusListener.aidl
+++ b/location/java/android/location/IGnssStatusListener.aidl
@@ -26,7 +26,7 @@
     void onGnssStarted();
     void onGnssStopped();
     void onFirstFix(int ttff);
-    void onSvStatusChanged(int svCount, in int[] prnWithFlags, in float[] snrs,
-            in float[] elevations, in float[] azimuths, in int[] constellationTypes);
+    void onSvStatusChanged(int svCount, in int[] svidWithFlags, in float[] snrs,
+            in float[] elevations, in float[] azimuths);
     void onNmeaReceived(long timestamp, String nmea);
 }
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 30cf101..23f0710 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1562,10 +1562,9 @@
 
         @Override
         public void onSvStatusChanged(int svCount, int[] prnWithFlags,
-                float[] snrs, float[] elevations, float[] azimuths, int[] constellationTypes) {
+                float[] snrs, float[] elevations, float[] azimuths) {
             if (mGnssCallback != null) {
-                mGnssStatus = new GnssStatus(svCount, prnWithFlags, snrs, elevations, azimuths,
-                        constellationTypes);
+                mGnssStatus = new GnssStatus(svCount, prnWithFlags, snrs, elevations, azimuths);
 
                 Message msg = Message.obtain();
                 msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index c194711..a3bbdfc 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
@@ -242,6 +243,7 @@
     private int mFlags = 0x0;
     private HashSet<String> mTags;
     private String mFormattedTags;
+    private Bundle mBundle; // lazy-initialized, may be null
 
     private AudioAttributes() {
     }
@@ -295,6 +297,20 @@
 
     /**
      * @hide
+     * Return the Bundle of data.
+     * @return a copy of the Bundle for this instance, may be null.
+     */
+    @SystemApi
+    public Bundle getBundle() {
+        if (mBundle == null) {
+            return mBundle;
+        } else {
+            return new Bundle(mBundle);
+        }
+    }
+
+    /**
+     * @hide
      * Return the set of tags.
      * @return a read-only set of all tags stored as strings.
      */
@@ -327,6 +343,7 @@
         private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
         private int mFlags = 0x0;
         private HashSet<String> mTags = new HashSet<String>();
+        private Bundle mBundle;
 
         /**
          * Constructs a new Builder with the defaults.
@@ -365,6 +382,9 @@
             aa.mFlags = mFlags;
             aa.mTags = (HashSet<String>) mTags.clone();
             aa.mFormattedTags = TextUtils.join(";", mTags);
+            if (mBundle != null) {
+                aa.mBundle = new Bundle(mBundle);
+            }
             return aa;
         }
 
@@ -453,6 +473,25 @@
 
         /**
          * @hide
+         * Adds a Bundle of data
+         * @param bundle a non-null Bundle
+         * @return the same builder instance
+         */
+        @SystemApi
+        public Builder addBundle(@NonNull Bundle bundle) {
+            if (bundle == null) {
+                throw new IllegalArgumentException("Illegal null bundle");
+            }
+            if (mBundle == null) {
+                mBundle = new Bundle(bundle);
+            } else {
+                mBundle.putAll(bundle);
+            }
+            return this;
+        }
+
+        /**
+         * @hide
          * Add a custom tag stored as a string
          * @param tag
          * @return the same Builder instance.
@@ -584,6 +623,10 @@
      * see definition of kAudioAttributesMarshallTagFlattenTags
      */
     public final static int FLATTEN_TAGS = 0x1;
+
+    private final static int ATTR_PARCEL_IS_NULL_BUNDLE = -1977;
+    private final static int ATTR_PARCEL_IS_VALID_BUNDLE = 1980;
+
     /**
      * When adding tags for writeToParcel(Parcel, int), add them in the list of flags (| NEW_FLAG)
      */
@@ -602,6 +645,12 @@
         } else if ((flags & FLATTEN_TAGS) == FLATTEN_TAGS) {
             dest.writeString(mFormattedTags);
         }
+        if (mBundle == null) {
+            dest.writeInt(ATTR_PARCEL_IS_NULL_BUNDLE);
+        } else {
+            dest.writeInt(ATTR_PARCEL_IS_VALID_BUNDLE);
+            dest.writeBundle(mBundle);
+        }
     }
 
     private AudioAttributes(Parcel in) {
@@ -621,6 +670,16 @@
             }
             mFormattedTags = TextUtils.join(";", mTags);
         }
+        switch (in.readInt()) {
+            case ATTR_PARCEL_IS_NULL_BUNDLE:
+                mBundle = null;
+                break;
+            case ATTR_PARCEL_IS_VALID_BUNDLE:
+                mBundle = new Bundle(in.readBundle());
+                break;
+            default:
+                Log.e(TAG, "Illegal value unmarshalling AudioAttributes, can't initialize bundle");
+        }
     }
 
     public static final Parcelable.Creator<AudioAttributes> CREATOR
@@ -655,7 +714,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mContentType, mFlags, mSource, mUsage, mFormattedTags);
+        return Objects.hash(mContentType, mFlags, mSource, mUsage, mFormattedTags, mBundle);
     }
 
     @Override
@@ -664,7 +723,8 @@
                 + " usage=" + mUsage
                 + " content=" + mContentType
                 + " flags=0x" + Integer.toHexString(mFlags).toUpperCase()
-                + " tags=" + mFormattedTags);
+                + " tags=" + mFormattedTags
+                + " bundle=" + (mBundle == null ? "null" : mBundle.toString()));
     }
 
     /** @hide */
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 800b914..e342385 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1014,9 +1014,12 @@
      * Reads audio data from the audio hardware for recording into a byte array.
      * The format specified in the AudioRecord constructor should be
      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
      * @param audioData the array to which the recorded audio data is written.
-     * @param offsetInBytes index in audioData from which the data is written expressed in bytes.
+     * @param offsetInBytes index in audioData to which the data is written expressed in bytes.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInBytes the number of requested bytes.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
      *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
      *     is read.
@@ -1025,7 +1028,8 @@
      * @return the number of bytes that were read or {@link #ERROR_INVALID_OPERATION}
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
-     *    The number of bytes will not exceed sizeInBytes.
+     *    The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
      */
     public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
             @ReadMode int readMode) {
@@ -1053,12 +1057,14 @@
      * The format specified in the AudioRecord constructor should be
      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
      * @param audioData the array to which the recorded audio data is written.
-     * @param offsetInShorts index in audioData from which the data is written expressed in shorts.
+     * @param offsetInShorts index in audioData to which the data is written expressed in shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInShorts the number of requested shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @return the number of shorts that were read or {@link #ERROR_INVALID_OPERATION}
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
-     *    The number of shorts will not exceed sizeInShorts.
+     *    The number of shorts will be a multiple of the channel count not to exceed sizeInShorts.
      */
     public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
         return read(audioData, offsetInShorts, sizeInShorts, READ_BLOCKING);
@@ -1070,7 +1076,9 @@
      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
      * @param audioData the array to which the recorded audio data is written.
      * @param offsetInShorts index in audioData from which the data is written expressed in shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInShorts the number of requested shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
      *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
      *     is read.
@@ -1079,7 +1087,7 @@
      * @return the number of shorts that were read or {@link #ERROR_INVALID_OPERATION}
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
-     *    The number of shorts will not exceed sizeInShorts.
+     *    The number of shorts will be a multiple of the channel count not to exceed sizeInShorts.
      */
     public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
             @ReadMode int readMode) {
@@ -1108,7 +1116,9 @@
      * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array.
      * @param audioData the array to which the recorded audio data is written.
      * @param offsetInFloats index in audioData from which the data is written.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInFloats the number of requested floats.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
      * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
      *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
      *     is read.
@@ -1117,7 +1127,7 @@
      * @return the number of floats that were read or {@link #ERROR_INVALID_OPERATION}
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
-     *    The number of floats will not exceed sizeInFloats.
+     *    The number of floats will be a multiple of the channel count not to exceed sizeInFloats.
      */
     public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
             @ReadMode int readMode) {
@@ -1154,6 +1164,7 @@
      * The representation of the data in the buffer will depend on the format specified in
      * the AudioRecord constructor, and will be native endian.
      * @param audioBuffer the direct buffer to which the recorded audio data is written.
+     * Data is written to audioBuffer.position().
      * @param sizeInBytes the number of requested bytes. It is recommended but not enforced
      *    that the number of bytes requested be a multiple of the frame size (sample size in
      *    bytes multiplied by the channel count).
@@ -1161,7 +1172,7 @@
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
      *    The number of bytes will not exceed sizeInBytes.
-     *    The number of bytes read will truncated to be a multiple of the frame size.
+     *    The number of bytes read will be truncated to be a multiple of the frame size.
      */
     public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) {
         return read(audioBuffer, sizeInBytes, READ_BLOCKING);
@@ -1175,6 +1186,7 @@
      * The representation of the data in the buffer will depend on the format specified in
      * the AudioRecord constructor, and will be native endian.
      * @param audioBuffer the direct buffer to which the recorded audio data is written.
+     * Data is written to audioBuffer.position().
      * @param sizeInBytes the number of requested bytes. It is recommended but not enforced
      *    that the number of bytes requested be a multiple of the frame size (sample size in
      *    bytes multiplied by the channel count).
@@ -1187,7 +1199,7 @@
      *    if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if
      *    the parameters don't resolve to valid data and indexes.
      *    The number of bytes will not exceed sizeInBytes.
-     *    The number of bytes read will truncated to be a multiple of the frame size.
+     *    The number of bytes read will be truncated to be a multiple of the frame size.
      */
     public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @ReadMode int readMode) {
         if (mState != STATE_INITIALIZED) {
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b26b310..6fc2f87 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -885,10 +885,10 @@
     // postcondition:
     //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
     private void audioBuffSizeCheck(int audioBufferSize) {
-        // NB: this section is only valid with PCM data.
+        // NB: this section is only valid with PCM or IEC61937 data.
         //     To update when supporting compressed formats
         int frameSizeInBytes;
-        if (AudioFormat.isEncodingLinearPcm(mAudioFormat)) {
+        if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
             frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
         } else {
             frameSizeInBytes = 1;
@@ -1052,32 +1052,27 @@
         }
     }
 
-// TODO Change getBufferCapacityInFrames() reference below to
-// {@link #getBufferCapacityInFrames()} after @hide is removed.
-// TODO Change setBufferSizeInFrames(int) reference below to
-// {@link #setBufferSizeInFrames(int)} after @hide is removed.
+
     /**
-     *  Returns the effective size of the <code>AudioTrack</code> buffer
+     * Returns the effective size of the <code>AudioTrack</code> buffer
      * that the application writes to.
-     *  <p> This will be less than or equal to the result of
-     * getBufferCapacityInFrames().
-     * It will be equal if setBufferSizeInFrames(int) has never been called.
-     *  <p> If the track is subsequently routed to a different output sink, the buffer
-     *  size and capacity may enlarge to accommodate.
-     *  <p> If the <code>AudioTrack</code> encoding indicates compressed data,
-     *  e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
-     *  the size of the native <code>AudioTrack</code> buffer in bytes.
-     *  <p> See also {@link AudioManager#getProperty(String)} for key
-     *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
-     *  @return current size in frames of the <code>AudioTrack</code> buffer.
-     *  @throws IllegalStateException
+     * <p> This will be less than or equal to the result of
+     * {@link #getBufferCapacityInFrames()}.
+     * It will be equal if {@link #setBufferSizeInFrames(int)} has never been called.
+     * <p> If the track is subsequently routed to a different output sink, the buffer
+     * size and capacity may enlarge to accommodate.
+     * <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+     * e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+     * the size of the native <code>AudioTrack</code> buffer in bytes.
+     * <p> See also {@link AudioManager#getProperty(String)} for key
+     * {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+     * @return current size in frames of the <code>AudioTrack</code> buffer.
+     * @throws IllegalStateException
      */
     public int getBufferSizeInFrames() {
         return native_get_buffer_size_frames();
     }
 
-// TODO Change getBufferCapacityInFrames() reference below to
-// {@link #getBufferCapacityInFrames()} after @hide is removed.
     /**
      * Limits the effective size of the <code>AudioTrack</code> buffer
      * that the application writes to.
@@ -1087,9 +1082,9 @@
      * <p>Changing this limit modifies the latency associated with
      * the buffer for this track. A smaller size will give lower latency
      * but there may be more glitches due to buffer underruns.
-     *  <p>The actual size used may not be equal to this requested size.
+     * <p>The actual size used may not be equal to this requested size.
      * It will be limited to a valid range with a maximum of
-     * getBufferCapacityInFrames().
+     * {@link #getBufferCapacityInFrames()}.
      * It may also be adjusted slightly for internal reasons.
      * If bufferSizeInFrames is less than zero then {@link #ERROR_BAD_VALUE}
      * will be returned.
@@ -1097,9 +1092,9 @@
      * It is not supported for compressed audio tracks.
      *
      * @param bufferSizeInFrames requested buffer size
-     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
-     *    {@link #ERROR_INVALID_OPERATION}
-     *  @throws IllegalStateException
+     * @return the actual buffer size in frames or an error code,
+     *    {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
+     * @throws IllegalStateException
      */
     public int setBufferSizeInFrames(int bufferSizeInFrames) {
         if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
@@ -1774,6 +1769,7 @@
      * or copies audio data for later playback (static buffer mode).
      * The format specified in the AudioTrack constructor should be
      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
      * <p>
      * In streaming mode, the write will normally block until all the data has been enqueued for
      * playback, and will return a full transfer count.  However, if the track is stopped or paused
@@ -1786,7 +1782,9 @@
      * @param audioData the array that holds the data to play.
      * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
      *    starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInBytes the number of bytes to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @return zero or the positive number of bytes that were written, or
      *    {@link #ERROR_INVALID_OPERATION}
      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
@@ -1795,6 +1793,8 @@
      *    needs to be recreated.
      *    The dead object error code is not returned if some data was successfully transferred.
      *    In this case, the error is returned at the next write().
+     *    The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
      *
      * This is equivalent to {@link #write(byte[], int, int, int)} with <code>writeMode</code>
      * set to  {@link #WRITE_BLOCKING}.
@@ -1808,6 +1808,7 @@
      * or copies audio data for later playback (static buffer mode).
      * The format specified in the AudioTrack constructor should be
      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
      * <p>
      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
@@ -1823,7 +1824,9 @@
      * @param audioData the array that holds the data to play.
      * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
      *    starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInBytes the number of bytes to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
      *     effect in static mode.
      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
@@ -1838,6 +1841,8 @@
      *    needs to be recreated.
      *    The dead object error code is not returned if some data was successfully transferred.
      *    In this case, the error is returned at the next write().
+     *    The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
      */
     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
             @WriteMode int writeMode) {
@@ -1887,7 +1892,9 @@
      * @param audioData the array that holds the data to play.
      * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
      *     starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInShorts the number of shorts to read in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @return zero or the positive number of shorts that were written, or
      *    {@link #ERROR_INVALID_OPERATION}
      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
@@ -1896,6 +1903,7 @@
      *    needs to be recreated.
      *    The dead object error code is not returned if some data was successfully transferred.
      *    In this case, the error is returned at the next write().
+     *    The number of shorts will be a multiple of the channel count not to exceed sizeInShorts.
      *
      * This is equivalent to {@link #write(short[], int, int, int)} with <code>writeMode</code>
      * set to  {@link #WRITE_BLOCKING}.
@@ -1923,7 +1931,9 @@
      * @param audioData the array that holds the data to write.
      * @param offsetInShorts the offset expressed in shorts in audioData where the data to write
      *     starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInShorts the number of shorts to read in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
      *     effect in static mode.
      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
@@ -1938,6 +1948,7 @@
      *    needs to be recreated.
      *    The dead object error code is not returned if some data was successfully transferred.
      *    In this case, the error is returned at the next write().
+     *    The number of shorts will be a multiple of the channel count not to exceed sizeInShorts.
      */
     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
             @WriteMode int writeMode) {
@@ -1999,7 +2010,9 @@
      *     to provide samples values within the nominal range.
      * @param offsetInFloats the offset, expressed as a number of floats,
      *     in audioData where the data to write starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param sizeInFloats the number of floats to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
      *     effect in static mode.
      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
@@ -2014,6 +2027,7 @@
      *    needs to be recreated.
      *    The dead object error code is not returned if some data was successfully transferred.
      *    In this case, the error is returned at the next write().
+     *    The number of floats will be a multiple of the channel count not to exceed sizeInFloats.
      */
     public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
             @WriteMode int writeMode) {
@@ -2075,7 +2089,9 @@
      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
      *     have been advanced to reflect the amount of data that was successfully written to
      *     the AudioTrack.
-     * @param sizeInBytes number of bytes to write.
+     * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
+     *     that the number of bytes requested be a multiple of the frame size (sample size in
+     *     bytes multiplied by the channel count).
      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
      *     effect in static mode.
@@ -2142,7 +2158,9 @@
      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
      *     have been advanced to reflect the amount of data that was successfully written to
      *     the AudioTrack.
-     * @param sizeInBytes number of bytes to write.
+     * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
+     *     that the number of bytes requested be a multiple of the frame size (sample size in
+     *     bytes multiplied by the channel count).
      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}.
      *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index 4b6b4fa..8618ec9 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -32,8 +32,8 @@
 import java.util.Map;
 
 /**
- * MediaMuxer facilitates muxing elementary streams. Currently only supports an
- * mp4 file as the output and at most one audio and/or one video elementary
+ * MediaMuxer facilitates muxing elementary streams. Currently supports mp4 or
+ * webm file as the output and at most one audio and/or one video elementary
  * stream.
  * <p>
  * It is generally used like this:
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index f09f654..60444e0 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -277,6 +277,30 @@
         public static final int HOTWORD = 1999;
     }
 
+    // TODO make AudioSource static (API change) and move this method inside the AudioSource class
+    /**
+     * @hide
+     * @param source An audio source to test
+     * @return true if the source is only visible to system components
+     */
+    public static boolean isSystemOnlyAudioSource(int source) {
+        switch(source) {
+        case AudioSource.DEFAULT:
+        case AudioSource.MIC:
+        case AudioSource.VOICE_UPLINK:
+        case AudioSource.VOICE_DOWNLINK:
+        case AudioSource.VOICE_CALL:
+        case AudioSource.CAMCORDER:
+        case AudioSource.VOICE_RECOGNITION:
+        case AudioSource.VOICE_COMMUNICATION:
+        //case REMOTE_SUBMIX:  considered "system" as it requires system permissions
+        case AudioSource.UNPROCESSED:
+            return false;
+        default:
+            return true;
+        }
+    }
+
     /**
      * Defines the video source. These constants are used with
      * {@link MediaRecorder#setVideoSource(int)}.
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index 54543ec..e197141 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -42,7 +42,7 @@
 @SystemApi
 public class AudioMixingRule {
 
-    private AudioMixingRule(int mixType, ArrayList<AttributeMatchCriterion> criteria) {
+    private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria) {
         mCriteria = criteria;
         mTargetMixType = mixType;
     }
@@ -91,21 +91,21 @@
     public static final int RULE_EXCLUDE_UID =
             RULE_EXCLUSION_MASK | RULE_MATCH_UID;
 
-    static final class AttributeMatchCriterion {
+    static final class AudioMixMatchCriterion {
         final AudioAttributes mAttr;
-        final Integer mIntProp;
+        final int mIntProp;
         final int mRule;
 
         /** input parameters must be valid */
-        AttributeMatchCriterion(AudioAttributes attributes, int rule) {
+        AudioMixMatchCriterion(AudioAttributes attributes, int rule) {
             mAttr = attributes;
-            mIntProp = null;
+            mIntProp = Integer.MIN_VALUE;
             mRule = rule;
         }
         /** input parameters must be valid */
-        AttributeMatchCriterion(Integer intProp, int rule) {
+        AudioMixMatchCriterion(Integer intProp, int rule) {
             mAttr = null;
-            mIntProp = intProp;
+            mIntProp = intProp.intValue();
             mRule = rule;
         }
 
@@ -125,10 +125,10 @@
                 dest.writeInt(mAttr.getCapturePreset());
                 break;
             case RULE_MATCH_UID:
-                dest.writeInt(mIntProp.intValue());
+                dest.writeInt(mIntProp);
                 break;
             default:
-                Log.e("AttributeMatchCriterion", "Unknown match rule" + match_rule
+                Log.e("AudioMixMatchCriterion", "Unknown match rule" + match_rule
                         + " when writing to Parcel");
                 dest.writeInt(-1);
             }
@@ -137,8 +137,8 @@
 
     private final int mTargetMixType;
     int getTargetMixType() { return mTargetMixType; }
-    private final ArrayList<AttributeMatchCriterion> mCriteria;
-    ArrayList<AttributeMatchCriterion> getCriteria() { return mCriteria; }
+    private final ArrayList<AudioMixMatchCriterion> mCriteria;
+    ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
 
     @Override
     public int hashCode() {
@@ -205,7 +205,7 @@
      */
     @SystemApi
     public static class Builder {
-        private ArrayList<AttributeMatchCriterion> mCriteria;
+        private ArrayList<AudioMixMatchCriterion> mCriteria;
         private int mTargetMixType = AudioMix.MIX_TYPE_INVALID;
 
         /**
@@ -213,7 +213,7 @@
          */
         @SystemApi
         public Builder() {
-            mCriteria = new ArrayList<AttributeMatchCriterion>();
+            mCriteria = new ArrayList<AudioMixMatchCriterion>();
         }
 
         /**
@@ -378,10 +378,10 @@
                 throw new IllegalArgumentException("Incompatible rule for mix");
             }
             synchronized (mCriteria) {
-                Iterator<AttributeMatchCriterion> crIterator = mCriteria.iterator();
+                Iterator<AudioMixMatchCriterion> crIterator = mCriteria.iterator();
                 final int match_rule = rule & ~RULE_EXCLUSION_MASK;
                 while (crIterator.hasNext()) {
-                    final AttributeMatchCriterion criterion = crIterator.next();
+                    final AudioMixMatchCriterion criterion = crIterator.next();
                     switch (match_rule) {
                         case RULE_MATCH_ATTRIBUTE_USAGE:
                             // "usage"-based rule
@@ -413,7 +413,7 @@
                             break;
                         case RULE_MATCH_UID:
                             // "usage"-based rule
-                            if (criterion.mIntProp.intValue() == intProp.intValue()) {
+                            if (criterion.mIntProp == intProp.intValue()) {
                                 if (criterion.mRule == rule) {
                                     // rule already exists, we're done
                                     return this;
@@ -431,10 +431,10 @@
                 switch (match_rule) {
                     case RULE_MATCH_ATTRIBUTE_USAGE:
                     case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
-                        mCriteria.add(new AttributeMatchCriterion(attrToMatch, rule));
+                        mCriteria.add(new AudioMixMatchCriterion(attrToMatch, rule));
                         break;
                     case RULE_MATCH_UID:
-                        mCriteria.add(new AttributeMatchCriterion(intProp, rule));
+                        mCriteria.add(new AudioMixMatchCriterion(intProp, rule));
                         break;
                     default:
                         throw new IllegalStateException("Unreachable code in addRuleInternal()");
diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
index 5ad6126..5d2bac0 100644
--- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java
+++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java
@@ -17,7 +17,7 @@
 package android.media.audiopolicy;
 
 import android.media.AudioFormat;
-import android.media.audiopolicy.AudioMixingRule.AttributeMatchCriterion;
+import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -86,9 +86,9 @@
             dest.writeInt(mix.getFormat().getEncoding());
             dest.writeInt(mix.getFormat().getChannelMask());
             // write mix rules
-            final ArrayList<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
+            final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
             dest.writeInt(criteria.size());
-            for (AttributeMatchCriterion criterion : criteria) {
+            for (AudioMixMatchCriterion criterion : criteria) {
                 criterion.writeToParcel(dest);
             }
         }
@@ -150,8 +150,8 @@
             textDump += "  channels=0x";
             textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() +"\n";
             // write mix rules
-            final ArrayList<AttributeMatchCriterion> criteria = mix.getRule().getCriteria();
-            for (AttributeMatchCriterion criterion : criteria) {
+            final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
+            for (AudioMixMatchCriterion criterion : criteria) {
                 switch(criterion.mRule) {
                     case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE:
                         textDump += "  exclude usage ";
@@ -171,11 +171,11 @@
                         break;
                     case AudioMixingRule.RULE_MATCH_UID:
                         textDump += "  match UID ";
-                        textDump += criterion.mIntProp.toString();
+                        textDump += criterion.mIntProp;
                         break;
                     case AudioMixingRule.RULE_EXCLUDE_UID:
                         textDump += "  exclude UID ";
-                        textDump += criterion.mIntProp.toString();
+                        textDump += criterion.mIntProp;
                         break;
                     default:
                         textDump += "invalid rule!";
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 56b2514..2f72df6 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -470,7 +470,7 @@
             sub = new Subscription();
             mSubscriptions.put(parentId, sub);
         }
-        sub.add(callback, options);
+        sub.putCallback(options, callback);
 
         // If we are connected, tell the service that we are watching. If we aren't connected,
         // the service will be told when we connect.
@@ -502,7 +502,7 @@
         Subscription sub = mSubscriptions.get(parentId);
 
         // Tell the service if necessary.
-        if (sub != null && sub.remove(options) && mState == CONNECT_STATE_CONNECTED) {
+        if (sub != null && sub.removeCallback(options) && mState == CONNECT_STATE_CONNECTED) {
             try {
                 // NOTE: Do not call removeSubscriptionWithOptions when options are null. Otherwise,
                 // it will break the action of support library which expects removeSubscription will
@@ -1093,7 +1093,16 @@
             return mCallbacks;
         }
 
-        public void add(SubscriptionCallback callback, Bundle options) {
+        public SubscriptionCallback getCallback(Bundle options) {
+            for (int i = 0; i < mOptionsList.size(); ++i) {
+                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
+                    return mCallbacks.get(i);
+                }
+            }
+            return null;
+        }
+
+        public void putCallback(Bundle options, SubscriptionCallback callback) {
             for (int i = 0; i < mOptionsList.size(); ++i) {
                 if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
                     mCallbacks.set(i, callback);
@@ -1104,7 +1113,7 @@
             mOptionsList.add(options);
         }
 
-        public boolean remove(Bundle options) {
+        public boolean removeCallback(Bundle options) {
             for (int i = 0; i < mOptionsList.size(); ++i) {
                 if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
                     mCallbacks.remove(i);
@@ -1114,14 +1123,5 @@
             }
             return false;
         }
-
-        public SubscriptionCallback getCallback(Bundle options) {
-            for (int i = 0; i < mOptionsList.size(); ++i) {
-                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
-                    return mCallbacks.get(i);
-                }
-            }
-            return null;
-        }
     }
 }
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetector.java b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
index 707db06..8f022db 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetector.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetector.java
@@ -16,12 +16,17 @@
 
 package android.media.soundtrigger;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.AudioFormat;
 import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -29,6 +34,8 @@
 import com.android.internal.app.ISoundTriggerService;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.UUID;
 
 /**
@@ -45,6 +52,12 @@
     private static final boolean DBG = false;
     private static final String TAG = "SoundTriggerDetector";
 
+    private static final int MSG_AVAILABILITY_CHANGED = 1;
+    private static final int MSG_SOUND_TRIGGER_DETECTED = 2;
+    private static final int MSG_DETECTION_ERROR = 3;
+    private static final int MSG_DETECTION_PAUSE = 4;
+    private static final int MSG_DETECTION_RESUME = 5;
+
     private final Object mLock = new Object();
 
     private final ISoundTriggerService mSoundTriggerService;
@@ -53,7 +66,121 @@
     private final Handler mHandler;
     private final RecognitionCallback mRecognitionCallback;
 
-    public abstract class Callback {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                RECOGNITION_FLAG_NONE,
+                RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
+                RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
+            })
+    public @interface RecognitionFlags {}
+
+    /**
+     * Empty flag for {@link #startRecognition(int)}.
+     *
+     *  @hide
+     */
+    public static final int RECOGNITION_FLAG_NONE = 0;
+
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates
+     * whether the trigger audio for hotword needs to be captured.
+     */
+    public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 0x1;
+
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates
+     * whether the recognition should keep going on even after the
+     * model triggers.
+     * If this flag is specified, it's possible to get multiple
+     * triggers after a call to {@link #startRecognition(int)}, if the model
+     * triggers multiple times.
+     * When this isn't specified, the default behavior is to stop recognition once the
+     * trigger happenss, till the caller starts recognition again.
+     */
+    public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
+
+    /**
+     * Additional payload for {@link Callback#onDetected}.
+     */
+    public static class EventPayload {
+        private final boolean mTriggerAvailable;
+
+        // Indicates if {@code captureSession} can be used to continue capturing more audio
+        // from the DSP hardware.
+        private final boolean mCaptureAvailable;
+        // The session to use when attempting to capture more audio from the DSP hardware.
+        private final int mCaptureSession;
+        private final AudioFormat mAudioFormat;
+        // Raw data associated with the event.
+        // This is the audio that triggered the keyphrase if {@code isTriggerAudio} is true.
+        private final byte[] mData;
+
+        private EventPayload(boolean triggerAvailable, boolean captureAvailable,
+                AudioFormat audioFormat, int captureSession, byte[] data) {
+            mTriggerAvailable = triggerAvailable;
+            mCaptureAvailable = captureAvailable;
+            mCaptureSession = captureSession;
+            mAudioFormat = audioFormat;
+            mData = data;
+        }
+
+        /**
+         * Gets the format of the audio obtained using {@link #getTriggerAudio()}.
+         * May be null if there's no audio present.
+         */
+        @Nullable
+        public AudioFormat getCaptureAudioFormat() {
+            return mAudioFormat;
+        }
+
+        /**
+         * Gets the raw audio that triggered the keyphrase.
+         * This may be null if the trigger audio isn't available.
+         * If non-null, the format of the audio can be obtained by calling
+         * {@link #getCaptureAudioFormat()}.
+         *
+         * @see AlwaysOnHotwordDetector#RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO
+         */
+        @Nullable
+        public byte[] getTriggerAudio() {
+            if (mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the session ID to start a capture from the DSP.
+         * This may be null if streaming capture isn't possible.
+         * If non-null, the format of the audio that can be captured can be
+         * obtained using {@link #getCaptureAudioFormat()}.
+         *
+         * TODO: Candidate for Public API when the API to start capture with a session ID
+         * is made public.
+         *
+         * TODO: Add this to {@link #getCaptureAudioFormat()}:
+         * "Gets the format of the audio obtained using {@link #getTriggerAudio()}
+         * or {@link #getCaptureSession()}. May be null if no audio can be obtained
+         * for either the trigger or a streaming session."
+         *
+         * TODO: Should this return a known invalid value instead?
+         *
+         * @hide
+         */
+        @Nullable
+        public Integer getCaptureSession() {
+            if (mCaptureAvailable) {
+                return mCaptureSession;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    public static abstract class Callback {
         /**
          * Called when the availability of the sound model changes.
          */
@@ -63,7 +190,7 @@
          * Called when the sound model has triggered (such as when it matched a
          * given sound pattern).
          */
-        public abstract void onDetected();
+        public abstract void onDetected(@NonNull EventPayload eventPayload);
 
         /**
          *  Called when the detection fails due to an error.
@@ -95,9 +222,9 @@
         mSoundModelId = soundModelId;
         mCallback = callback;
         if (handler == null) {
-            mHandler = new Handler();
+            mHandler = new MyHandler();
         } else {
-            mHandler = handler;
+            mHandler = new MyHandler(handler.getLooper());
         }
         mRecognitionCallback = new RecognitionCallback();
     }
@@ -107,13 +234,19 @@
      * {@link Callback}.
      * @return Indicates whether the call succeeded or not.
      */
-    public boolean startRecognition() {
+    public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
         if (DBG) {
             Slog.d(TAG, "startRecognition()");
         }
+        boolean captureTriggerAudio =
+                (recognitionFlags & RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
+
+        boolean allowMultipleTriggers =
+                (recognitionFlags & RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
         try {
             mSoundTriggerService.startRecognition(new ParcelUuid(mSoundModelId),
-                    mRecognitionCallback);
+                    mRecognitionCallback, new RecognitionConfig(captureTriggerAudio,
+                        allowMultipleTriggers, null, null));
         } catch (RemoteException e) {
             return false;
         }
@@ -144,17 +277,25 @@
 
     /**
      * Callback that handles events from the lower sound trigger layer.
+     *
+     * Note that these callbacks will be called synchronously from the SoundTriggerService
+     * layer and thus should do minimal work (such as sending a message on a handler to do
+     * the real work).
      * @hide
      */
-    private static class RecognitionCallback extends
-            IRecognitionStatusCallback.Stub {
+    private class RecognitionCallback extends IRecognitionStatusCallback.Stub {
 
         /**
          * @hide
          */
         @Override
         public void onDetected(SoundTrigger.RecognitionEvent event) {
-            Slog.e(TAG, "onDetected()" + event);
+            Slog.d(TAG, "onDetected()" + event);
+            Message.obtain(mHandler,
+                    MSG_SOUND_TRIGGER_DETECTED,
+                    new EventPayload(event.triggerInData, event.captureAvailable,
+                            event.captureFormat, event.captureSession, event.data))
+                    .sendToTarget();
         }
 
         /**
@@ -162,7 +303,8 @@
          */
         @Override
         public void onError(int status) {
-            Slog.e(TAG, "onError()" + status);
+            Slog.d(TAG, "onError()" + status);
+            mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
         }
 
         /**
@@ -170,7 +312,8 @@
          */
         @Override
         public void onRecognitionPaused() {
-            Slog.e(TAG, "onRecognitionPaused()");
+            Slog.d(TAG, "onRecognitionPaused()");
+            mHandler.sendEmptyMessage(MSG_DETECTION_PAUSE);
         }
 
         /**
@@ -178,7 +321,44 @@
          */
         @Override
         public void onRecognitionResumed() {
-            Slog.e(TAG, "onRecognitionResumed()");
+            Slog.d(TAG, "onRecognitionResumed()");
+            mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
+        }
+    }
+
+    private class MyHandler extends Handler {
+
+        MyHandler() {
+            super();
+        }
+
+        MyHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mCallback == null) {
+                  Slog.w(TAG, "Received message: " + msg.what + " for NULL callback.");
+                  return;
+            }
+            switch (msg.what) {
+                case MSG_SOUND_TRIGGER_DETECTED:
+                    mCallback.onDetected((EventPayload) msg.obj);
+                    break;
+                case MSG_DETECTION_ERROR:
+                    mCallback.onError();
+                    break;
+                case MSG_DETECTION_PAUSE:
+                    mCallback.onRecognitionPaused();
+                    break;
+                case MSG_DETECTION_RESUME:
+                    mCallback.onRecognitionResumed();
+                    break;
+                default:
+                    super.handleMessage(msg);
+
+            }
         }
     }
 }
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index 8ef5ca0..5dd4e85 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -45,8 +45,7 @@
     void onTimeShiftCurrentPositionChanged(long timeMs, int seq);
 
     // For the recording session
-    void onConnected(int seq);
-    void onRecordingStarted(int seq);
+    void onTuned(int seq);
     void onRecordingStopped(in Uri recordedProgramUri, int seq);
     void onError(int error, int seq);
 }
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index d189333..3ec7656 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -41,7 +41,7 @@
 interface ITvInputManager {
     List<TvInputInfo> getTvInputList(int userId);
     TvInputInfo getTvInputInfo(in String inputId, int userId);
-    void setTvInputInfo(in TvInputInfo inputInfo, int userId);
+    void updateTvInputInfo(in TvInputInfo inputInfo, int userId);
     int getTvInputState(in String inputId, int userId);
 
     List<TvContentRatingSystemInfo> getTvContentRatingSystemList(int userId);
@@ -87,8 +87,7 @@
     void timeShiftEnablePositionTracking(in IBinder sessionToken, boolean enable, int userId);
 
     // For the recording session
-    void connect(in IBinder sessionToken, in Uri channelUri, in Bundle params, int userId);
-    void startRecording(in IBinder sessionToken, int userId);
+    void startRecording(in IBinder sessionToken, in Uri programHint, int userId);
     void stopRecording(in IBinder sessionToken, int userId);
 
     // For TV input hardware binding
diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl
index 395c9f3..0f8bf2f 100644
--- a/media/java/android/media/tv/ITvInputManagerCallback.aidl
+++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl
@@ -26,8 +26,6 @@
     void onInputAdded(in String inputId);
     void onInputRemoved(in String inputId);
     void onInputUpdated(in String inputId);
-
     void onInputStateChanged(in String inputId, int state);
-
-    void onTvInputInfoChanged(in TvInputInfo TvInputInfo);
+    void onTvInputInfoUpdated(in TvInputInfo TvInputInfo);
 }
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 408a762..b1ce8d4 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -56,8 +56,6 @@
     void timeShiftEnablePositionTracking(boolean enable);
 
     // For the recording session
-    void connect(in Uri channelUri, in Bundle params);
-    void disconnect();
-    void startRecording();
+    void startRecording(in Uri programHint);
     void stopRecording();
 }
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index cb6a05e..60d6f0d 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -42,8 +42,7 @@
     void onTimeShiftCurrentPositionChanged(long timeMs);
 
     // For the recording session
-    void onConnected();
-    void onRecordingStarted();
+    void onTuned();
     void onRecordingStopped(in Uri recordedProgramUri);
     void onError(int error);
 }
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 4ac5876..56103ad 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -16,6 +16,7 @@
 
 package android.media.tv;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Rect;
 import android.media.PlaybackParams;
@@ -65,10 +66,8 @@
     private static final int DO_TIME_SHIFT_SEEK_TO = 17;
     private static final int DO_TIME_SHIFT_SET_PLAYBACK_PARAMS = 18;
     private static final int DO_TIME_SHIFT_ENABLE_POSITION_TRACKING = 19;
-    private static final int DO_CONNECT = 20;
-    private static final int DO_DISCONNECT = 21;
-    private static final int DO_START_RECORDING = 22;
-    private static final int DO_STOP_RECORDING = 23;
+    private static final int DO_START_RECORDING = 20;
+    private static final int DO_STOP_RECORDING = 21;
 
     private final boolean mIsRecordingSession;
     private final HandlerCaller mCaller;
@@ -90,6 +89,7 @@
         }
     }
 
+    // For the recording session
     public ITvInputSessionWrapper(Context context,
             TvInputService.RecordingSession recordingSessionImpl) {
         mIsRecordingSession = true;
@@ -99,25 +99,28 @@
 
     @Override
     public void executeMessage(Message msg) {
-        if (!mIsRecordingSession && mTvInputSessionImpl == null) {
-            return;
-        }
-        if (mIsRecordingSession && mTvInputRecordingSessionImpl == null) {
+        if ((mIsRecordingSession && mTvInputRecordingSessionImpl == null)
+                || (!mIsRecordingSession && mTvInputSessionImpl == null)) {
             return;
         }
 
         long startTime = System.nanoTime();
         switch (msg.what) {
             case DO_RELEASE: {
-                mTvInputSessionImpl.release();
-                mTvInputSessionImpl = null;
-                if (mReceiver != null) {
-                    mReceiver.dispose();
-                    mReceiver = null;
-                }
-                if (mChannel != null) {
-                    mChannel.dispose();
-                    mChannel = null;
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.release();
+                    mTvInputRecordingSessionImpl = null;
+                } else {
+                    mTvInputSessionImpl.release();
+                    mTvInputSessionImpl = null;
+                    if (mReceiver != null) {
+                        mReceiver.dispose();
+                        mReceiver = null;
+                    }
+                    if (mChannel != null) {
+                        mChannel.dispose();
+                        mChannel = null;
+                    }
                 }
                 break;
             }
@@ -141,7 +144,11 @@
             }
             case DO_TUNE: {
                 SomeArgs args = (SomeArgs) msg.obj;
-                mTvInputSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+                } else {
+                    mTvInputSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+                }
                 args.recycle();
                 break;
             }
@@ -208,19 +215,8 @@
                 mTvInputSessionImpl.timeShiftEnablePositionTracking((Boolean) msg.obj);
                 break;
             }
-            case DO_CONNECT: {
-                SomeArgs args = (SomeArgs) msg.obj;
-                mTvInputRecordingSessionImpl.connect((Uri) args.arg1, (Bundle) args.arg2);
-                args.recycle();
-                break;
-            }
-            case DO_DISCONNECT: {
-                mTvInputRecordingSessionImpl.disconnect();
-                mTvInputRecordingSessionImpl = null;
-                break;
-            }
             case DO_START_RECORDING: {
-                mTvInputRecordingSessionImpl.startRecording();
+                mTvInputRecordingSessionImpl.startRecording((Uri) msg.obj);
                 break;
             }
             case DO_STOP_RECORDING: {
@@ -250,7 +246,9 @@
 
     @Override
     public void release() {
-        mTvInputSessionImpl.scheduleOverlayViewCleanup();
+        if (!mIsRecordingSession) {
+            mTvInputSessionImpl.scheduleOverlayViewCleanup();
+        }
         mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_RELEASE));
     }
 
@@ -354,20 +352,8 @@
     }
 
     @Override
-    public void connect(Uri channelUri, Bundle params) {
-        // Clear the pending connect requests.
-        mCaller.removeMessages(DO_CONNECT);
-        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CONNECT, channelUri, params));
-    }
-
-    @Override
-    public void disconnect() {
-        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_DISCONNECT));
-    }
-
-    @Override
-    public void startRecording() {
-        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_START_RECORDING));
+    public void startRecording(@Nullable Uri programHint) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_START_RECORDING, programHint));
     }
 
     @Override
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 62a01dc..9203ef2 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -27,6 +27,7 @@
 import android.provider.BaseColumns;
 import android.util.ArraySet;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -1020,22 +1021,28 @@
          *
          * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
          * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
-         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty.
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Genres#encode} to create a text that can be stored in this column. Use
+         * {@link Genres#decode} to get the broadcast genre strings from the text stored in the
+         * column.
          *
          * <p>Type: TEXT
+         * @see Genres#encode
+         * @see Genres#decode
          */
         public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre";
 
         /**
          * The comma-separated canonical genre string of this TV program.
          *
-         * <p>Canonical genres are defined in {@link Genres}. Use
-         * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column.
-         * Use {@link Genres#decode Genres.decode()} to get the canonical genre strings from the
-         * text stored in this column.
+         * <p>Canonical genres are defined in {@link Genres}. Use {@link Genres#encode} to create a
+         * text that can be stored in this column. Use {@link Genres#decode} to get the canonical
+         * genre strings from the text stored in the column.
          *
          * <p>Type: TEXT
          * @see Genres
+         * @see Genres#encode
+         * @see Genres#decode
          */
         public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";
 
@@ -1303,34 +1310,87 @@
                 CANONICAL_GENRES.add(TECH_SCIENCE);
             }
 
+            private static final char DOUBLE_QUOTE = '"';
+            private static final char COMMA = ',';
+            private static final String DELIMITER = ",";
+
             private Genres() {}
 
             /**
-             * Encodes canonical genre strings to a text that can be put into the database.
+             * Encodes genre strings to a text that can be put into the database.
              *
-             * @param genres Canonical genre strings. Use the strings defined in this class.
+             * @param genres Genre strings.
              * @return an encoded genre string that can be inserted into the
-             *         {@link #COLUMN_CANONICAL_GENRE} column.
+             *         {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
              */
             public static String encode(String... genres) {
                 StringBuilder sb = new StringBuilder();
                 String separator = "";
                 for (String genre : genres) {
-                    sb.append(separator).append(genre);
-                    separator = ",";
+                    sb.append(separator).append(encodeToCsv(genre));
+                    separator = DELIMITER;
+                }
+                return sb.toString();
+            }
+
+            private static String encodeToCsv(String genre) {
+                StringBuilder sb = new StringBuilder();
+                int length = genre.length();
+                for (int i = 0; i < length; ++i) {
+                    char c = genre.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                        case COMMA:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                    }
+                    sb.append(c);
                 }
                 return sb.toString();
             }
 
             /**
-             * Decodes the canonical genre strings from the text stored in the database.
+             * Decodes the genre strings from the text stored in the database.
              *
              * @param genres The encoded genre string retrieved from the
-             *            {@link #COLUMN_CANONICAL_GENRE} column.
-             * @return canonical genre strings.
+             *            {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
+             * @return genre strings.
              */
             public static String[] decode(String genres) {
-                return genres.split("\\s*,\\s*");
+                StringBuilder sb = new StringBuilder();
+                List<String> results = new ArrayList<>();
+                int length = genres.length();
+                boolean escape = false;
+                for (int i = 0; i < length; ++i) {
+                    char c = genres.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            if (!escape) {
+                                escape = true;
+                                continue;
+                            }
+                            break;
+                        case COMMA:
+                            if (!escape) {
+                                String string = sb.toString().trim();
+                                if (string.length() > 0) {
+                                    results.add(string);
+                                }
+                                sb = new StringBuilder();
+                                continue;
+                            }
+                            break;
+                    }
+                    sb.append(c);
+                    escape = false;
+                }
+                String string = sb.toString().trim();
+                if (string.length() > 0) {
+                    results.add(string);
+                }
+                return results.toArray(new String[results.size()]);
             }
 
             /**
@@ -1366,6 +1426,17 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
 
         /**
+         * The ID of the TV input service that is associated with this recorded program.
+         *
+         * <p>Use {@link #buildInputId} to build the ID.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INPUT_ID = "input_id";
+
+        /**
          * The ID of the TV channel that provided this recorded TV program.
          *
          * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
@@ -1441,7 +1512,10 @@
          *
          * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
          * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
-         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty.
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column.
+         * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the
+         * text stored in the column.
          *
          * <p>Type: TEXT
          * @see Programs#COLUMN_BROADCAST_GENRE
@@ -1454,7 +1528,7 @@
          * <p>Canonical genres are defined in {@link Programs.Genres}. Use
          * {@link Programs.Genres#encode Genres.encode()} to create a text that can be stored in
          * this column. Use {@link Programs.Genres#decode Genres.decode()} to get the canonical
-         * genre strings from the text stored in this column.
+         * genre strings from the text stored in the column.
          *
          * <p>Type: TEXT
          * @see Programs#COLUMN_CANONICAL_GENRE
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index c6dece4..f0a9426 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -421,9 +421,7 @@
      * @param context Supplies a {@link Context} used to check if this TV input is hidden.
      * @return {@code true} if the user marked this TV input hidden in settings. {@code false}
      *         otherwise.
-     * @hide
      */
-    @SystemApi
     public boolean isHidden(Context context) {
         return TvInputSettings.isHidden(context, mId, UserHandle.myUserId());
     }
@@ -451,9 +449,7 @@
      * @param context Supplies a {@link Context} used to load the custom label.
      * @return a CharSequence containing the TV input's custom label. {@code null} if there is no
      *         custom label.
-     * @hide
      */
-    @SystemApi
     public CharSequence loadCustomLabel(Context context) {
         return TvInputSettings.getCustomLabel(context, mId, UserHandle.myUserId());
     }
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 1cd1958..51aae90 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -83,110 +83,127 @@
     static final int VIDEO_UNAVAILABLE_REASON_END = 4;
 
     /**
-     * A generic reason. Video is not available due to an unspecified error.
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to
+     * an unspecified error.
      */
     public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = VIDEO_UNAVAILABLE_REASON_START;
     /**
-     * Video is not available because the TV input is in the middle of tuning to a new channel.
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the corresponding TV input is in the middle of tuning to a new channel.
      */
     public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1;
     /**
-     * Video is not available due to the weak TV signal.
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to
+     * weak TV signal.
      */
     public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2;
     /**
-     * Video is not available because the TV input stopped the playback temporarily to buffer more
-     * data.
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the corresponding TV input has stopped playback temporarily to buffer more data.
      */
     public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3;
     /**
-     * Video is not available because the current program is audio-only.
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the current TV program is audio-only.
      */
     public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = VIDEO_UNAVAILABLE_REASON_END;
 
     /**
-     * Status prior to calling {@link TvInputService.Session#notifyTimeShiftStatusChanged}.
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Unknown status. Also
+     * the status prior to calling {@code notifyTimeShiftStatusChanged}.
      */
     public static final int TIME_SHIFT_STATUS_UNKNOWN = 0;
 
     /**
-     * The TV input does not support time shifting.
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: The current TV input
+     * does not support time shifting.
      */
     public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1;
 
     /**
-     * Time shifting is currently not available but might work again later.
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is
+     * currently unavailable but might work again later.
      */
     public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2;
 
     /**
-     * Time shifting is currently available. In this status, the application assumes it can
-     * pause/resume playback, seek to a specified time position and set playback rate and audio
-     * mode.
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is
+     * currently available. In this status, the application assumes it can pause/resume playback,
+     * seek to a specified time position and set playback rate and audio mode.
      */
     public static final int TIME_SHIFT_STATUS_AVAILABLE = 3;
 
+    /**
+     * Value returned by {@link TvInputService.Session#onTimeShiftGetCurrentPosition()} and
+     * {@link TvInputService.Session#onTimeShiftGetStartPosition()} when time shifting has not
+     * yet started.
+     */
     public static final long TIME_SHIFT_INVALID_TIME = Long.MIN_VALUE;
 
     /**
-     * RecordingError when a requested operation cannot be completed due to a problem that does not
-     * fit under any other error code.
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: The requested operation cannot be
+     * completed due to a problem that does not fit under any other error codes.
      */
     public static final int RECORDING_ERROR_UNKNOWN = 0;
 
     /**
-     * RecordingError when an attempt to connect to a recording session has failed or the
-     * established connection has been disconnected without a known reason.
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed due to
+     * insufficient storage space.
      */
-    public static final int RECORDING_ERROR_CONNECTION_FAILED = 1;
+    public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1;
 
     /**
-     * RecordingError when recording cannot proceed due to insufficient storage space.
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed because
+     * a required recording resource was not able to be allocated.
      */
-    public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 2;
-
-    /**
-     * RecordingError when recording cannot proceed because the required recording resource is not
-     * able to be allocated.
-     */
-    public static final int RECORDING_ERROR_RESOURCE_BUSY = 3;
+    public static final int RECORDING_ERROR_RESOURCE_BUSY = 2;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef({RECORDING_ERROR_UNKNOWN, RECORDING_ERROR_CONNECTION_FAILED,
-            RECORDING_ERROR_INSUFFICIENT_SPACE, RECORDING_ERROR_RESOURCE_BUSY})
+    @IntDef({RECORDING_ERROR_UNKNOWN, RECORDING_ERROR_INSUFFICIENT_SPACE,
+            RECORDING_ERROR_RESOURCE_BUSY})
     public @interface RecordingError {}
 
     /**
-     * The TV input is connected.
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected.
      *
-     * <p>This state indicates that a source device is connected to the input port and is in the
-     * normal operation mode. It is mostly relevant to hardware inputs such as HDMI input.
+     * <p>This state indicates that a source device is connected to the input port and in the normal
+     * operation mode. It is mostly relevant to hardware inputs such as HDMI input.
      * Non-hardware inputs are considered connected all the time.
-     *
-     * @see #getInputState
-     * @see TvInputManager.TvInputCallback#onInputStateChanged
      */
     public static final int INPUT_STATE_CONNECTED = 0;
+
     /**
-     * The TV input is connected but in standby mode.
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected but
+     * in standby mode.
      *
-     * <p>This state indicates that a source device is connected to the input port but is in standby
-     * or low power mode. It is mostly relevant to hardware inputs such as HDMI inputs and Component
+     * <p>This state indicates that a source device is connected to the input port and in standby or
+     * low power mode. It is mostly relevant to hardware inputs such as HDMI inputs and Component
      * inputs.
-     *
-     * @see #getInputState
-     * @see TvInputManager.TvInputCallback#onInputStateChanged
      */
     public static final int INPUT_STATE_CONNECTED_STANDBY = 1;
+
     /**
-     * The TV input is disconnected.
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is disconnected.
      *
      * <p>This state indicates that a source device is disconnected from the input port. It is
      * mostly relevant to hardware inputs such as HDMI input.
      *
-     * @see #getInputState
-     * @see TvInputManager.TvInputCallback#onInputStateChanged
      */
     public static final int INPUT_STATE_DISCONNECTED = 2;
 
@@ -449,33 +466,29 @@
         public void onTimeShiftCurrentPositionChanged(Session session, long timeMs) {
         }
 
+        // For the recording session only
         /**
-         * This is called when a recording session initiated by a call to {@link
-         * TvRecordingClient#connect(String, Uri)} has been established.
+         * This is called when the recording session has been tuned to the given channel and is
+         * ready to start recording.
          */
-        void onConnected(Session session) {
+        void onTuned(Session session) {
         }
 
+        // For the recording session only
         /**
-         * This is called when TV program recording on the current channel has started.
+         * This is called when the current recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
          *
-         * @param session A {@link TvInputManager.Session} associated with this callback.
-         */
-        void onRecordingStarted(Session session) {
-        }
-
-        /**
-         * This is called when TV program recording on the current channel has stopped. The passed
-         * URI contains information about the new recorded program.
-         *
-         * @param recordedProgramUri The URI for the new recorded program.
-         * @see android.media.tv.TvContract.RecordedPrograms
+         * @param recordedProgramUri The URI for the newly recorded program.
          **/
         void onRecordingStopped(Session session, Uri recordedProgramUri) {
         }
 
+        // For the recording session only
         /**
-         * This is called when an issue has occurred before or during recording.
+         * This is called when an issue has occurred. It may be called at any time after the current
+         * recording session is created until it is released.
          *
          * @param error The error code.
          */
@@ -632,21 +645,11 @@
         }
 
         // For the recording session only
-        void postConnected() {
+        void postTuned() {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mSessionCallback.onConnected(mSession);
-                }
-            });
-        }
-
-        // For the recording session only
-        void postRecordingStarted() {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mSessionCallback.onRecordingStarted(mSession);
+                    mSessionCallback.onTuned(mSession);
                 }
             });
         }
@@ -724,11 +727,17 @@
         }
 
         /**
-         * This is called when the information about a given TV input has been changed.
+         * This is called when the information about an existing TV input has been updated.
          *
-         * @param inputInfo TvInputInfo object that contains the information about the TV input.
+         * <p>Because the system automatically creates a <code>TvInputInfo</code> object for each TV
+         * input based on the information collected from the <code>AndroidManifest.xml</code>, this
+         * method is only called back when such information has changed dynamically or when the TV
+         * input service implementation wants to pass additional information that is not specified
+         * by the manifest file, such as ability to record and tuner count.
+         *
+         * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
          */
-        public void onTvInputInfoChanged(TvInputInfo inputInfo) {
+        public void onTvInputInfoUpdated(TvInputInfo inputInfo) {
         }
     }
 
@@ -781,11 +790,11 @@
             });
         }
 
-        public void postTvInputInfoChanged(final TvInputInfo inputInfo) {
+        public void postTvInputInfoUpdated(final TvInputInfo inputInfo) {
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    mCallback.onTvInputInfoChanged(inputInfo);
+                    mCallback.onTvInputInfoUpdated(inputInfo);
                 }
             });
         }
@@ -998,26 +1007,14 @@
             }
 
             @Override
-            public void onConnected(int seq) {
+            public void onTuned(int seq) {
                 synchronized (mSessionCallbackRecordMap) {
                     SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
                     if (record == null) {
                         Log.e(TAG, "Callback not found for seq " + seq);
                         return;
                     }
-                    record.postConnected();
-                }
-            }
-
-            @Override
-            public void onRecordingStarted(int seq) {
-                synchronized (mSessionCallbackRecordMap) {
-                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
-                    if (record == null) {
-                        Log.e(TAG, "Callback not found for seq " + seq);
-                        return;
-                    }
-                    record.postRecordingStarted();
+                    record.postTuned();
                 }
             }
 
@@ -1086,10 +1083,10 @@
             }
 
             @Override
-            public void onTvInputInfoChanged(TvInputInfo inputInfo) {
+            public void onTvInputInfoUpdated(TvInputInfo inputInfo) {
                 synchronized (mLock) {
                     for (TvInputCallbackRecord record : mCallbackRecords) {
-                        record.postTvInputInfoChanged(inputInfo);
+                        record.postTvInputInfoUpdated(inputInfo);
                     }
                 }
             }
@@ -1140,19 +1137,19 @@
     }
 
     /**
-     * Sets a new TvInputInfo object for a given input.
+     * Updates information about an existing TV input.
      *
      * <p>This is called internally only by {@link TvInputService}.
      *
-     * @param inputInfo The TvInputInfo object to set.
+     * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
      * @throws IllegalArgumentException if the argument is {@code null}.
      */
-    void setTvInputInfo(@NonNull TvInputInfo inputInfo) {
+    void updateTvInputInfo(@NonNull TvInputInfo inputInfo) {
         Preconditions.checkNotNull(inputInfo);
         try {
-            mService.setTvInputInfo(inputInfo, mUserId);
+            mService.updateTvInputInfo(inputInfo, mUserId);
         } catch (RemoteException e) {
-            throw new RuntimeException("Error trying to set " + inputInfo, e);
+            throw new RuntimeException("Error trying to update " + inputInfo, e);
         }
     }
 
@@ -2013,48 +2010,25 @@
         }
 
         /**
-         * Connects to a given channel for TV program recording.
-         */
-        void connect(Uri channelUri) {
-            connect(channelUri, null);
-        }
-
-        /**
-         * Tunes to a given channel.
+         * Starts TV program recording in the current recording session.
          *
-         * @param channelUri The URI of a channel.
-         * @param params Extra parameters.
+         * @param programHint The URI for the TV program to record as a hint, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
          */
-        void connect(@NonNull Uri channelUri, Bundle params) {
-            Preconditions.checkNotNull(channelUri);
+        void startRecording(@Nullable Uri programHint) {
             if (mToken == null) {
                 Log.w(TAG, "The session has been already released");
                 return;
             }
             try {
-                mService.connect(mToken, channelUri, params, mUserId);
+                mService.startRecording(mToken, programHint, mUserId);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
         }
 
         /**
-         * Starts TV program recording for the current recording session.
-         */
-        void startRecording() {
-            if (mToken == null) {
-                Log.w(TAG, "The session has been already released");
-                return;
-            }
-            try {
-                mService.startRecording(mToken, mUserId);
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        /**
-         * Stops TV program recording for the current recording session.
+         * Stops TV program recording in the current recording session.
          */
         void stopRecording() {
             if (mToken == null) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index d48b2c8..da4a038 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -255,23 +255,31 @@
         return null;
     }
 
-
     /**
-     * Sets the TvInputInfo for this TV input.
+     * Updates the <code>TvInputInfo</code> for an existing TV input. A TV input service
+     * implementation may call this method to pass the application and system an up-to-date
+     * <code>TvInputInfo</code> object that describes itself.
      *
-     * <p>The system service automatically creates the TvInputInfo for each TV input based on
-     * information collected from the AndroidManifest.xml, thus it is not necessary to call this
-     * method unless the TV input has additional information to pass such as ability to record and
-     * tuner count. Attempting to change information about a TV input that the calling package does
-     * not own does nothing.
+     * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input,
+     * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not
+     * necessary to call this method unless such information has changed dynamically. This may be
+     * also used to pass additional information that is not specified by the manifest file, such as
+     * ability to record and tuner count. Use {@link TvInputInfo.Builder} to build a new
+     * <code>TvInputInfo</code> object.
+     *
+     * <p>Attempting to change information about a TV input that the calling package does not own
+     * does nothing.
      *
      * @param context The application context.
-     * @param inputInfo The TvInputInfo object that contains that new information.
+     * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
+     * @see TvInputManager.TvInputCallback#onTvInputInfoUpdated(TvInputInfo)
      */
-    public static final void setTvInputInfo(Context context, TvInputInfo inputInfo) {
+    public static final void updateTvInputInfo(Context context, TvInputInfo inputInfo) {
         TvInputManager manager = (TvInputManager) context.getSystemService(
                 Context.TV_INPUT_SERVICE);
-        manager.setTvInputInfo(inputInfo);
+        if (manager != null) {
+            manager.updateTvInputInfo(inputInfo);
+        }
     }
 
     private boolean isPassthroughInput(String inputId) {
@@ -1545,7 +1553,7 @@
         private final List<Runnable> mPendingActions = new ArrayList<>();
 
         /**
-         * Creates a new Recording Session for TV program recording.
+         * Creates a new RecordingSession.
          *
          * @param context The context of the application
          */
@@ -1554,51 +1562,41 @@
         }
 
         /**
-         * Informs the application that recording session has been connected.
-         */
-        public void notifyConnected() {
-            executeOrPostRunnableOnMainThread(new Runnable() {
-                @MainThread
-                @Override
-                public void run() {
-                    try {
-                        if (DEBUG) Log.d(TAG, "notifyConnected");
-                        if (mSessionCallback != null) {
-                            mSessionCallback.onConnected();
-                        }
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "error in notifyConnected", e);
-                    }
-                }
-            });
-        }
-
-        /**
-         * Informs the application that recording has started.
-         */
-        public void notifyRecordingStarted() {
-            executeOrPostRunnableOnMainThread(new Runnable() {
-                @MainThread
-                @Override
-                public void run() {
-                    try {
-                        if (DEBUG) Log.d(TAG, "notifyRecordingStarted");
-                        if (mSessionCallback != null) {
-                            mSessionCallback.onRecordingStarted();
-                        }
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "error in notifyRecordingStarted", e);
-                    }
-                }
-            });
-        }
-
-        /**
-         * Informs the application that recording has stopped successfully. Each TV input service
-         * should create a new data entry in the recorded programs table upon completion of the
-         * recording and send its URI.
+         * Informs the application that this recording session has been tuned to the given channel
+         * and is ready to start recording.
          *
-         * @param recordedProgramUri The URI of the new recorded program.
+         * <p>Upon receiving a call to {@link #onTune(Uri)}, the session is expected to tune to the
+         * passed channel and call this method to indicate that it is now available for immediate
+         * recording. When {@link #onStartRecording(Uri)} is called, recording must start with
+         * minimal delay.
+         */
+        public void notifyTuned() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTuned");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTuned();
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTuned", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that this recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
+         *
+         * <p>The recording session must call this method in response to {@link #onStopRecording()}.
+         * The session may call it even before receiving a call to {@link #onStopRecording()} if a
+         * partially recorded program is available when there is an error.
+         *
+         * @param recordedProgramUri The URI of the newly recorded program.
          */
         public void notifyRecordingStopped(final Uri recordedProgramUri) {
             executeOrPostRunnableOnMainThread(new Runnable() {
@@ -1618,12 +1616,18 @@
         }
 
         /**
-         * Sends an error to the application at any moment.
+         * Informs the application that there is an error and this recording session is no longer
+         * able to start or continue recording. It may be called at any time after the recording
+         * session is created until {@link #onRelease()} is called.
+         *
+         * <p>The application may release the current session upon receiving the error code through
+         * {@link TvRecordingClient.RecordingCallback#onError(int)}. The session may call
+         * {@link #notifyRecordingStopped(Uri)} if a partially recorded but still playable program
+         * is available, before calling this method.
          *
          * @param error The error code. Should be one of the followings.
          * <ul>
          * <li>{@link TvInputManager#RECORDING_ERROR_UNKNOWN}
-         * <li>{@link TvInputManager#RECORDING_ERROR_CONNECTION_FAILED}
          * <li>{@link TvInputManager#RECORDING_ERROR_INSUFFICIENT_SPACE}
          * <li>{@link TvInputManager#RECORDING_ERROR_RESOURCE_BUSY}
          * </ul>
@@ -1672,46 +1676,75 @@
         }
 
         /**
-         * Called when the recording session is connected.
+         * Called when the application requests to tune to a given channel for TV program recording.
          *
-         * @param channelUri The URI of the channel.
+         * <p>The application may call this method before starting or after stopping recording, but
+         * not during recording.
+         *
+         * <p>The session must call {@link #notifyTuned()} if the tune request was fulfilled, or
+         * {@link #notifyError(int)} otherwise.
+         *
+         * @param channelUri The URI of a channel.
          */
-        public abstract void onConnect(Uri channelUri);
+        public abstract void onTune(Uri channelUri);
 
         /**
-         * Called when the recording session is connected.
+         * Called when the application requests to tune to a given channel for TV program recording.
          *
-         * @param channelUri The URI of the channel.
+         * <p>The application may call this method before starting or after stopping recording, but
+         * not during recording.
+         *
+         * <p>The session must call {@link #notifyTuned()} if the tune request was fulfilled, or
+         * {@link #notifyError(int)} otherwise.
+         *
+         * @param channelUri The URI of a channel.
          * @param params Extra parameters.
          * @hide
          */
         @SystemApi
-        public void onConnect(Uri channelUri, Bundle params) {
-            onConnect(channelUri);
+        public void onTune(Uri channelUri, Bundle params) {
+            onTune(channelUri);
         }
 
         /**
-         * Called when the application requests to disconnect the current recording session.
+         * Called when the application requests to start TV program recording. Recording must start
+         * immediately when this method is called.
+         *
+         * <p>The application may supply the URI for a TV program as a hint for filling in program
+         * specific data fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+         * A non-null {@code programHint} implies the started recording should be of that specific
+         * program, whereas null {@code programHint} does not impose such a requirement and the
+         * recording can span across multiple TV programs. In either case, the application must call
+         * {@link TvRecordingClient#stopRecording()} to stop the recording.
+         *
+         * <p>The session must call {@link #notifyError(int)} if the start request cannot be
+         * fulfilled.
+         *
+         * @param programHint The URI for the TV program to record as a hint, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
          */
-        public abstract void onDisconnect();
+        public abstract void onStartRecording(@Nullable Uri programHint);
 
         /**
-         * Called when the application requests to start recording. Recording must start
-         * immediately.
+         * Called when the application requests to stop TV program recording. Recording must stop
+         * immediately when this method is called.
          *
-         * <p>The session must call either {@link #notifyRecordingStarted()} or
-         * {@link #notifyError(int)}}.
-         */
-        public abstract void onStartRecording();
-
-        /**
-         * Called when the application requests to stop recording. Recording must stop immediately.
+         * <p>The session must create a new data entry in the
+         * {@link android.media.tv.TvContract.RecordedPrograms} table that describes the newly
+         * recorded program and call {@link #notifyRecordingStopped(Uri)} with the URI to that
+         * entry.
+         * If the stop request cannot be fulfilled, the session must call {@link #notifyError(int)}.
          *
-         * <p>The session must call either {@link #notifyRecordingStopped(Uri)} or
-         * {@link #notifyError(int)}}.
          */
         public abstract void onStopRecording();
 
+
+        /**
+         * Called when the application requests to release all the resources held by this recording
+         * session.
+         */
+        public abstract void onRelease();
+
         /**
          * Processes a private command sent from the application to the TV input. This can be used
          * to provide domain-specific features that are only known between certain TV inputs and
@@ -1728,27 +1761,27 @@
         }
 
         /**
-         * Calls {@link #onConnect(Uri, Bundle)}.
+         * Calls {@link #onTune(Uri, Bundle)}.
          *
          */
-        void connect(Uri channelUri, Bundle params) {
-            onConnect(channelUri, params);
+        void tune(Uri channelUri, Bundle params) {
+            onTune(channelUri, params);
         }
 
         /**
-         * Calls {@link #onDisconnect()}.
+         * Calls {@link #onRelease()}.
          *
          */
-        void disconnect() {
-            onDisconnect();
+        void release() {
+            onRelease();
         }
 
         /**
-         * Calls {@link #onStartRecording()}.
+         * Calls {@link #onStartRecording(Uri)}.
          *
          */
-        void startRecording() {
-            onStartRecording();
+        void startRecording(@Nullable  Uri programHint) {
+            onStartRecording(programHint);
         }
 
         /**
@@ -1907,6 +1940,15 @@
          * </ul>
          */
         public void onHardwareVideoUnavailable(int reason) { }
+
+        @Override
+        void release() {
+            if (mHardwareSession != null) {
+                mHardwareSession.release();
+                mHardwareSession = null;
+            }
+            super.release();
+        }
     }
 
     /** @hide */
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index 1d80068..1c920f5 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -17,8 +17,10 @@
 package android.media.tv;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.media.tv.TvInputManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -45,12 +47,14 @@
     private TvInputManager.Session mSession;
     private MySessionCallback mSessionCallback;
 
+    private boolean mIsRecordingStarted;
+    private boolean mIsTuned;
     private final Queue<Pair<String, Bundle>> mPendingAppPrivateCommands = new ArrayDeque<>();
 
     /**
      * Creates a new TvRecordingClient object.
      *
-     * @param context The application context to create the TvRecordingClient with.
+     * @param context The application context to create a TvRecordingClient with.
      * @param tag A short name for debugging purposes.
      * @param callback The callback to receive recording status changes.
      * @param handler The handler to invoke the callback on.
@@ -63,25 +67,37 @@
     }
 
     /**
-     * Connects to a given input for TV program recording. This will create a new recording session
-     * from the TV input and establishes the connection between the application and the session.
+     * Tunes to a given channel for TV program recording. The first tune request will create a new
+     * recording session for the corresponding TV input and establish a connection between the
+     * application and the session. If recording has already started in the current recording
+     * session, this method throws an exception.
+     *
+     * <p>The application may call this method before starting or after stopping recording, but not
+     * during recording.
      *
      * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onConnected()} or {@link RecordingCallback#onError(int)}.
+     * {@link RecordingCallback#onTuned()} if the tune request was fulfilled, or
+     * {@link RecordingCallback#onError(int)} otherwise.
      *
      * @param inputId The ID of the TV input for the given channel.
      * @param channelUri The URI of a channel.
      */
-    public void connect(String inputId, Uri channelUri) {
-        connect(inputId, channelUri, null);
+    public void tune(String inputId, Uri channelUri) {
+        tune(inputId, channelUri, null);
     }
 
     /**
-     * Connects to a given input for TV program recording. This will create a new recording session
-     * from the TV input and establishes the connection between the application and the session.
+     * Tunes to a given channel for TV program recording. The first tune request will create a new
+     * recording session for the corresponding TV input and establish a connection between the
+     * application and the session. If recording has already started in the current recording
+     * session, this method throws an exception.
+     *
+     * <p>The application may call this method before starting or after stopping recording, but not
+     * during recording.
      *
      * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onConnected()} or {@link RecordingCallback#onError(int)}.
+     * {@link RecordingCallback#onTuned()} if the tune request was fulfilled, or
+     * {@link RecordingCallback#onError(int)} otherwise.
      *
      * @param inputId The ID of the TV input for the given channel.
      * @param channelUri The URI of a channel.
@@ -89,14 +105,17 @@
      * @hide
      */
     @SystemApi
-    public void connect(String inputId, Uri channelUri, Bundle params) {
-        if (DEBUG) Log.d(TAG, "connect(" + channelUri + ")");
+    public void tune(String inputId, Uri channelUri, Bundle params) {
+        if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
         if (TextUtils.isEmpty(inputId)) {
             throw new IllegalArgumentException("inputId cannot be null or an empty string");
         }
+        if (mIsRecordingStarted) {
+            throw new IllegalStateException("tune failed - recording already started");
+        }
         if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
             if (mSession != null) {
-                mSession.connect(channelUri, params);
+                mSession.tune(channelUri, params);
             } else {
                 mSessionCallback.mChannelUri = channelUri;
                 mSessionCallback.mConnectionParams = params;
@@ -111,13 +130,11 @@
     }
 
     /**
-     * Disconnects the established connection between the application and the recording session.
-     *
-     * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onDisconnected()} or {@link RecordingCallback#onError(int)}.
+     * Releases the resources in the current recording session immediately. This may be called at
+     * any time, however if the session is already released, it does nothing.
      */
-    public void disconnect() {
-        if (DEBUG) Log.d(TAG, "disconnect()");
+    public void release() {
+        if (DEBUG) Log.d(TAG, "release()");
         resetInternal();
     }
 
@@ -131,34 +148,57 @@
     }
 
     /**
-     * Starts TV program recording for the current recording session. It is expected that recording
-     * starts immediately after calling this method.
+     * Starts TV program recording in the current recording session. Recording is expected to start
+     * immediately when this method is called. If the current recording session has not yet tuned to
+     * any channel, this method throws an exception.
      *
-     * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onRecordingStarted()} or {@link RecordingCallback#onError(int)}.
+     * <p>The application may supply the URI for a TV program as a hint for filling in program
+     * specific data fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+     * A non-null {@code programHint} implies the started recording should be of that specific
+     * program, whereas null {@code programHint} does not impose such a requirement and the
+     * recording can span across multiple TV programs. In either case, the application must call
+     * {@link TvRecordingClient#stopRecording()} to stop the recording.
+     *
+     * <p>The recording session will respond by calling {@link RecordingCallback#onError(int)} if
+     * the start request cannot be fulfilled.
+     *
+     * @param programHint The URI for the TV program to record as a hint, built by
+     *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
      */
-    public void startRecording() {
+    public void startRecording(@Nullable Uri programHint) {
+        if (!mIsTuned) {
+            throw new IllegalStateException("startRecording failed - not yet tuned");
+        }
         if (mSession != null) {
-            mSession.startRecording();
+            mSession.startRecording(programHint);
+            mIsRecordingStarted = true;
         }
     }
 
     /**
-     * Stops TV program recording for the current recording session. It is expected that recording
-     * stops immediately after calling this method.
+     * Stops TV program recording in the current recording session. Recording is expected to stop
+     * immediately when this method is called. If recording has not yet started in the current
+     * recording session, this method does nothing.
      *
-     * <p>The recording session will respond by calling
-     * {@link RecordingCallback#onRecordingStopped(Uri)} or {@link RecordingCallback#onError(int)}.
+     * <p>The recording session is expected to create a new data entry in the
+     * {@link android.media.tv.TvContract.RecordedPrograms} table that describes the newly
+     * recorded program and pass the URI to that entry through to
+     * {@link RecordingCallback#onRecordingStopped(Uri)}.
+     * If the stop request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
      */
     public void stopRecording() {
+        if (!mIsRecordingStarted) {
+            Log.w(TAG, "stopRecording failed - recording not yet started");
+        }
         if (mSession != null) {
             mSession.stopRecording();
         }
     }
 
     /**
-     * Calls {@link TvInputService.RecordingSession#appPrivateCommand(String, Bundle)
-     * TvInputService.RecordingSession.appPrivateCommand()} on the current TvView.
+     * Calls {@link TvInputService.RecordingSession#appPrivateCommand(String, Bundle)} for the
+     * current recording session.
      *
      * @param action The name of the private command to send. This <em>must</em> be a scoped name,
      *            i.e. prefixed with a package name you own, so that different developers will not
@@ -186,46 +226,46 @@
      */
     public abstract static class RecordingCallback {
         /**
-         * This is called when a recording session initiated by a call to
-         * {@link #connect(String, Uri)} has been established.
-         */
-        public void onConnected() {
-        }
-
-        /**
-         * This is called when the established connection between the application and the recording
-         * session has been disconnected. Disconnection can be initiated either by an explicit
-         * request (i.e. a call to {@link #disconnect()} or by an error on the TV input service
-         * side.
-         */
-        public void onDisconnected() {
-        }
-
-        /**
-         * This is called when TV program recording on the current channel has started.
-         */
-        public void onRecordingStarted() {
-        }
-
-        /**
-         * This is called when TV program recording on the current channel has stopped. The passed
-         * URI contains information about the new recorded program.
+         * This is called when an error occurred while establishing a connection to the recording
+         * session for the corresponding TV input.
          *
-         * @param recordedProgramUri The URI for the new recorded program.
-         * @see android.media.tv.TvContract.RecordedPrograms
+         * @param inputId The ID of the TV input bound to the current TvRecordingClient.
+         */
+        public void onConnectionFailed(String inputId) {
+        }
+
+        /**
+         * This is called when the connection to the current recording session is lost.
+         *
+         * @param inputId The ID of the TV input bound to the current TvRecordingClient.
+         */
+        public void onDisconnected(String inputId) {
+        }
+
+        /**
+         * This is called when the recording session has been tuned to the given channel and is
+         * ready to start recording.
+         */
+        public void onTuned() {
+        }
+
+        /**
+         * This is called when the current recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
+         *
+         * @param recordedProgramUri The URI for the newly recorded program.
          */
         public void onRecordingStopped(Uri recordedProgramUri) {
         }
 
         /**
-         * This is called when an issue has occurred before or during recording. If the TV input
-         * service cannot proceed recording due to this error, a call to {@link #onDisconnected()}
-         * is expected to follow.
+         * This is called when an issue has occurred. It may be called at any time after the current
+         * recording session is created until it is released.
          *
          * @param error The error code. Should be one of the followings.
          * <ul>
          * <li>{@link TvInputManager#RECORDING_ERROR_UNKNOWN}
-         * <li>{@link TvInputManager#RECORDING_ERROR_CONNECTION_FAILED}
          * <li>{@link TvInputManager#RECORDING_ERROR_INSUFFICIENT_SPACE}
          * <li>{@link TvInputManager#RECORDING_ERROR_RESOURCE_BUSY}
          * </ul>
@@ -277,23 +317,26 @@
                     mSession.sendAppPrivateCommand(command.first, command.second);
                 }
                 mPendingAppPrivateCommands.clear();
-                mSession.connect(mChannelUri, mConnectionParams);
+                mSession.tune(mChannelUri, mConnectionParams);
             } else {
                 mSessionCallback = null;
-                mCallback.onError(TvInputManager.RECORDING_ERROR_CONNECTION_FAILED);
+                if (mCallback != null) {
+                    mCallback.onConnectionFailed(mInputId);
+                }
             }
         }
 
         @Override
-        void onConnected(TvInputManager.Session session) {
+        void onTuned(TvInputManager.Session session) {
             if (DEBUG) {
-                Log.d(TAG, "onConnected()");
+                Log.d(TAG, "onTuned()");
             }
             if (this != mSessionCallback) {
-                Log.w(TAG, "onConnected - session not created");
+                Log.w(TAG, "onTuned - session not created");
                 return;
             }
-            mCallback.onConnected();
+            mIsTuned = true;
+            mCallback.onTuned();
         }
 
         @Override
@@ -305,39 +348,32 @@
                 Log.w(TAG, "onSessionReleased - session not created");
                 return;
             }
+            mIsTuned = false;
+            mIsRecordingStarted = false;
             mSessionCallback = null;
             mSession = null;
-            mCallback.onDisconnected();
-        }
-
-        @Override
-        public void onRecordingStarted(TvInputManager.Session session) {
-            if (DEBUG) {
-                Log.d(TAG, "onRecordingStarted()");
+            if (mCallback != null) {
+                mCallback.onDisconnected(mInputId);
             }
-            if (this != mSessionCallback) {
-                Log.w(TAG, "onRecordingStarted - session not created");
-                return;
-            }
-            mCallback.onRecordingStarted();
         }
 
         @Override
         public void onRecordingStopped(TvInputManager.Session session, Uri recordedProgramUri) {
             if (DEBUG) {
-                Log.d(TAG, "onRecordingStopped()");
+                Log.d(TAG, "onRecordingStopped(recordedProgramUri= " + recordedProgramUri + ")");
             }
             if (this != mSessionCallback) {
                 Log.w(TAG, "onRecordingStopped - session not created");
                 return;
             }
+            mIsRecordingStarted = false;
             mCallback.onRecordingStopped(recordedProgramUri);
         }
 
         @Override
         public void onError(TvInputManager.Session session, int error) {
             if (DEBUG) {
-                Log.d(TAG, "onError()");
+                Log.d(TAG, "onError(error=" + error + ")");
             }
             if (this != mSessionCallback) {
                 Log.w(TAG, "onError - session not created");
@@ -350,7 +386,8 @@
         public void onSessionEvent(TvInputManager.Session session, String eventType,
                 Bundle eventArgs) {
             if (DEBUG) {
-                Log.d(TAG, "onSessionEvent(" + eventType + ")");
+                Log.d(TAG, "onSessionEvent(eventType=" + eventType + ", eventArgs=" + eventArgs
+                        + ")");
             }
             if (this != mSessionCallback) {
                 Log.w(TAG, "onSessionEvent - session not created");
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index ed432c46..6a44b1e 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -52,11 +52,14 @@
     private final int mVideoHeight;
     private final float mVideoFrameRate;
     private final float mVideoPixelAspectRatio;
+    private final byte mVideoActiveFormatDescription;
+
     private final Bundle mExtra;
 
     private TvTrackInfo(int type, String id, String language, CharSequence description,
             int audioChannelCount, int audioSampleRate, int videoWidth, int videoHeight,
-            float videoFrameRate, float videoPixelAspectRatio, Bundle extra) {
+            float videoFrameRate, float videoPixelAspectRatio, byte videoActiveFormatDescription,
+            Bundle extra) {
         mType = type;
         mId = id;
         mLanguage = language;
@@ -67,6 +70,7 @@
         mVideoHeight = videoHeight;
         mVideoFrameRate = videoFrameRate;
         mVideoPixelAspectRatio = videoPixelAspectRatio;
+        mVideoActiveFormatDescription = videoActiveFormatDescription;
         mExtra = extra;
     }
 
@@ -81,6 +85,7 @@
         mVideoHeight = in.readInt();
         mVideoFrameRate = in.readFloat();
         mVideoPixelAspectRatio = in.readFloat();
+        mVideoActiveFormatDescription = in.readByte();
         mExtra = in.readBundle();
     }
 
@@ -179,6 +184,20 @@
     }
 
     /**
+     * Returns the Active Format Description (AFD) code of the video.
+     * Valid only for {@link #TYPE_VIDEO} tracks.
+     *
+     * <p>The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
+     * 4 and SMPTE 2016-1-2007.
+     */
+    public final byte getVideoActiveFormatDescription() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoActiveFormatDescription;
+    }
+
+    /**
      * Returns the extra information about the current track.
      */
     public final Bundle getExtra() {
@@ -208,6 +227,7 @@
         dest.writeInt(mVideoHeight);
         dest.writeFloat(mVideoFrameRate);
         dest.writeFloat(mVideoPixelAspectRatio);
+        dest.writeByte(mVideoActiveFormatDescription);
         dest.writeBundle(mExtra);
     }
 
@@ -238,6 +258,7 @@
         private int mVideoHeight;
         private float mVideoFrameRate;
         private float mVideoPixelAspectRatio = 1.0f;
+        private byte mVideoActiveFormatDescription;
         private Bundle mExtra;
 
         /**
@@ -368,6 +389,25 @@
         }
 
         /**
+         * Sets the Active Format Description (AFD) code of the video.
+         * Valid only for {@link #TYPE_VIDEO} tracks.
+         *
+         * <p>This is needed for applications to be able to scale the video properly based on the
+         * information about where in the coded picture the active video is.
+         * The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
+         * 4 and SMPTE 2016-1-2007.
+         *
+         * @param videoActiveFormatDescription The AFD code of the video.
+         */
+        public final Builder setVideoActiveFormatDescription(byte videoActiveFormatDescription) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoActiveFormatDescription = videoActiveFormatDescription;
+            return this;
+        }
+
+        /**
          * Sets the extra information about the current track.
          *
          * @param extra The extra information.
@@ -385,7 +425,7 @@
         public TvTrackInfo build() {
             return new TvTrackInfo(mType, mId, mLanguage, mDescription, mAudioChannelCount,
                     mAudioSampleRate, mVideoWidth, mVideoHeight, mVideoFrameRate,
-                    mVideoPixelAspectRatio, mExtra);
+                    mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra);
         }
     }
 }
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 0132d24..5c4b528 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -539,8 +539,8 @@
     }
 
     /**
-     * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
-     * TvInputService.Session.appPrivateCommand()} on the current TvView.
+     * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)} for the current
+     * session.
      *
      * @param action The name of the private command to send. This <em>must</em> be a scoped name,
      *            i.e. prefixed with a package name you own, so that different developers will not
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 3372524..480acd9 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -121,7 +121,7 @@
      * be thrown.
      *
      * @see MediaBrowserService#onLoadChildren
-     * @see MediaBrowserService#onGetMediaItem
+     * @see MediaBrowserService#onLoadItem
      */
     public class Result<T> {
         private Object mDebug;
diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp
index e414f48..35da84c 100644
--- a/media/jni/android_media_MediaCrypto.cpp
+++ b/media/jni/android_media_MediaCrypto.cpp
@@ -25,7 +25,9 @@
 #include "JNIHelp.h"
 
 #include <binder/IServiceManager.h>
+#include <cutils/properties.h>
 #include <media/ICrypto.h>
+#include <media/IMediaDrmService.h>
 #include <media/IMediaPlayerService.h>
 #include <media/stagefright/foundation/ADebug.h>
 
@@ -61,19 +63,30 @@
 // static
 sp<ICrypto> JCrypto::MakeCrypto() {
     sp<IServiceManager> sm = defaultServiceManager();
+    sp<ICrypto> crypto;
 
-    sp<IBinder> binder =
-        sm->getService(String16("media.player"));
-
-    sp<IMediaPlayerService> service =
-        interface_cast<IMediaPlayerService>(binder);
-
-    if (service == NULL) {
-        return NULL;
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.mediadrmservice.enable", value, NULL)
+        && (!strcmp("1", value) || !strcasecmp("true", value))) {
+        sp<IBinder> binder =
+            sm->getService(String16("media.drm"));
+        sp<IMediaDrmService> service =
+            interface_cast<IMediaDrmService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        crypto = service->makeCrypto();
+    } else {
+        sp<IBinder> binder =
+            sm->getService(String16("media.player"));
+        sp<IMediaPlayerService> service =
+            interface_cast<IMediaPlayerService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        crypto = service->makeCrypto();
     }
 
-    sp<ICrypto> crypto = service->makeCrypto();
-
     if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
         return NULL;
     }
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index b8849c6..73ddedf 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -28,7 +28,9 @@
 
 #include <binder/IServiceManager.h>
 #include <binder/Parcel.h>
+#include <cutils/properties.h>
 #include <media/IDrm.h>
+#include <media/IMediaDrmService.h>
 #include <media/IMediaPlayerService.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaErrors.h>
@@ -352,19 +354,30 @@
 // static
 sp<IDrm> JDrm::MakeDrm() {
     sp<IServiceManager> sm = defaultServiceManager();
+    sp<IDrm> drm;
 
-    sp<IBinder> binder =
-        sm->getService(String16("media.player"));
-
-    sp<IMediaPlayerService> service =
-        interface_cast<IMediaPlayerService>(binder);
-
-    if (service == NULL) {
-        return NULL;
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("media.mediadrmservice.enable", value, NULL)
+        && (!strcmp("1", value) || !strcasecmp("true", value))) {
+        sp<IBinder> binder =
+            sm->getService(String16("media.drm"));
+        sp<IMediaDrmService> service =
+            interface_cast<IMediaDrmService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        drm = service->makeDrm();
+    } else {
+        sp<IBinder> binder =
+            sm->getService(String16("media.player"));
+        sp<IMediaPlayerService> service =
+            interface_cast<IMediaPlayerService>(binder);
+        if (service == NULL) {
+            return NULL;
+        }
+        drm = service->makeDrm();
     }
 
-    sp<IDrm> drm = service->makeDrm();
-
     if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
         return NULL;
     }
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index 6b9fdb6..7c1142b 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -7,6 +7,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
 LOCAL_STATIC_JAVA_LIBRARIES := easymocklib \
     mockito-target \
     core-tests \
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 9ac929b..58e7709 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -94,9 +94,8 @@
             android:name=".OpenExternalDirectoryActivity"
             android:theme="@android:style/Theme.Translucent.NoTitleBar">
             <intent-filter>
-                <action android:name="android.intent.action.OPEN_EXTERNAL_DIRECTORY" />
+                <action android:name="android.os.storage.action.OPEN_EXTERNAL_DIRECTORY" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <data android:scheme="file" />
             </intent-filter>
         </activity>
 
diff --git a/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow_am_alpha.png b/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow_am_alpha.png
deleted file mode 100644
index e4881dd..0000000
--- a/packages/DocumentsUI/res/drawable-hdpi/ic_subdirectory_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow_am_alpha.png b/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow_am_alpha.png
deleted file mode 100644
index 66725e5..0000000
--- a/packages/DocumentsUI/res/drawable-mdpi/ic_subdirectory_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow_am_alpha.png b/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow_am_alpha.png
deleted file mode 100644
index cdf21b1..0000000
--- a/packages/DocumentsUI/res/drawable-xhdpi/ic_subdirectory_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow_am_alpha.png b/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow_am_alpha.png
deleted file mode 100644
index 050313f..0000000
--- a/packages/DocumentsUI/res/drawable-xxhdpi/ic_subdirectory_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable-xxxhdpi/ic_subdirectory_arrow_am_alpha.png b/packages/DocumentsUI/res/drawable-xxxhdpi/ic_subdirectory_arrow_am_alpha.png
deleted file mode 100644
index 8fddb85..0000000
--- a/packages/DocumentsUI/res/drawable-xxxhdpi/ic_subdirectory_arrow_am_alpha.png
+++ /dev/null
Binary files differ
diff --git a/packages/DocumentsUI/res/drawable/ic_root_home.xml b/packages/DocumentsUI/res/drawable/ic_root_documents.xml
similarity index 86%
rename from packages/DocumentsUI/res/drawable/ic_root_home.xml
rename to packages/DocumentsUI/res/drawable/ic_root_documents.xml
index 696ee05..afd886d 100644
--- a/packages/DocumentsUI/res/drawable/ic_root_home.xml
+++ b/packages/DocumentsUI/res/drawable/ic_root_documents.xml
@@ -20,5 +20,5 @@
         android:viewportHeight="24.0">
     <path
         android:fillColor="#FF000000"
-        android:pathData="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
+        android:pathData="M10 4H4c-1.1 0,-1.99.9,-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2,-.9 2,-2V8c0,-1.1,-.9,-2,-2,-2h-8l-2,-2z"/>
 </vector>
diff --git a/packages/DocumentsUI/res/drawable/ic_subdirectory_arrow.xml b/packages/DocumentsUI/res/drawable/ic_subdirectory_arrow.xml
index 5723233..0f34ba4 100644
--- a/packages/DocumentsUI/res/drawable/ic_subdirectory_arrow.xml
+++ b/packages/DocumentsUI/res/drawable/ic_subdirectory_arrow.xml
@@ -1,5 +1,24 @@
-<?xml version="1.0" encoding="utf-8"?>
-<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/ic_subdirectory_arrow_am_alpha"
-    android:tint="?android:attr/colorControlNormal"
-    android:autoMirrored="true" />
+<!--
+Copyright (C) 2016 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="?android:attr/colorControlNormal"
+        android:pathData="M19 15l-6 6,-1.42,-1.42L15.17 16H4V4h2v10h9.17l-3.59,-3.58L13 9l6 6z"/>
+</vector>
diff --git a/packages/DocumentsUI/res/layout/directory_cluster.xml b/packages/DocumentsUI/res/layout/directory_cluster.xml
index 2fa09d3..d84ef08 100644
--- a/packages/DocumentsUI/res/layout/directory_cluster.xml
+++ b/packages/DocumentsUI/res/layout/directory_cluster.xml
@@ -27,6 +27,7 @@
 
     <FrameLayout
         android:id="@+id/container_directory"
+        android:clipToPadding="false"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1" />
diff --git a/packages/DocumentsUI/res/layout/fixed_layout.xml b/packages/DocumentsUI/res/layout/fixed_layout.xml
index 8414feb..84a928d 100644
--- a/packages/DocumentsUI/res/layout/fixed_layout.xml
+++ b/packages/DocumentsUI/res/layout/fixed_layout.xml
@@ -16,11 +16,14 @@
 
 <!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
      floating action buttons) to operate correctly. -->
+<!-- focusableInTouchMode is set in order to force key events to go to the activity's global key
+     callback, which is necessary for proper event routing. See BaseActivity.onKeyDown. -->
 <android.support.design.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:id="@+id/coordinator_layout">
+    android:id="@+id/coordinator_layout"
+    android:focusableInTouchMode="true">
 
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index 223d729..0d336f9 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -17,8 +17,10 @@
 <com.android.documentsui.DirectoryView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:animateLayoutChanges="true">
+    android:background="@color/window_background"
+    android:outlineProvider="bounds"
+    android:elevation="4dp"
+    android:orientation="vertical">
 
     <ProgressBar
         android:id="@+id/progressbar"
@@ -43,6 +45,9 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
+        android:background="@color/window_background"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
         android:visibility="gone">
 
         <LinearLayout
@@ -80,8 +85,7 @@
         android:layout_height="match_parent">
 
         <android.support.v7.widget.RecyclerView
-            android:id="@+id/list"
-            android:background="@color/window_background"
+            android:id="@+id/dir_list"
             android:scrollbars="vertical"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/packages/DocumentsUI/res/layout/fragment_roots.xml b/packages/DocumentsUI/res/layout/fragment_roots.xml
index f3de3b4..b33b8d0 100644
--- a/packages/DocumentsUI/res/layout/fragment_roots.xml
+++ b/packages/DocumentsUI/res/layout/fragment_roots.xml
@@ -14,8 +14,8 @@
      limitations under the License.
 -->
 
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@android:id/list"
+<com.android.documentsui.RootsList xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/roots_list"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:paddingTop="8dp"
diff --git a/packages/DocumentsUI/res/layout/item_subdir.xml b/packages/DocumentsUI/res/layout/item_subdir.xml
index b2a739a..821432d 100644
--- a/packages/DocumentsUI/res/layout/item_subdir.xml
+++ b/packages/DocumentsUI/res/layout/item_subdir.xml
@@ -26,8 +26,8 @@
 
     <ImageView
         android:id="@+id/subdir"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
         android:paddingEnd="8dp"
         android:scaleType="centerInside"
         android:visibility="gone"
diff --git a/packages/DocumentsUI/res/layout/single_pane_layout.xml b/packages/DocumentsUI/res/layout/single_pane_layout.xml
index f53d698..235d22d 100644
--- a/packages/DocumentsUI/res/layout/single_pane_layout.xml
+++ b/packages/DocumentsUI/res/layout/single_pane_layout.xml
@@ -16,11 +16,14 @@
 
 <!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
      floating action buttons) to operate correctly. -->
+<!-- focusableInTouchMode is set in order to force key events to go to the activity's global key 
+     callback, which is necessary for proper event routing. See BaseActivity.onKeyDown. -->
 <android.support.design.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:id="@+id/coordinator_layout">
+    android:id="@+id/coordinator_layout"
+    android:focusableInTouchMode="true">
 
     <LinearLayout
         android:layout_width="match_parent"
diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
index 7fb1d06..dc9a390 100644
--- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml
+++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml
@@ -26,7 +26,7 @@
     <string name="menu_list" msgid="7279285939892417279">"Siyahı görünüşü"</string>
     <string name="menu_sort" msgid="7677740407158414452">"Bunlardan biri üzrə sırala"</string>
     <string name="menu_search" msgid="3816712084502856974">"Axtarış"</string>
-    <string name="menu_settings" msgid="8239065133341597825">"Yaddaş parametrləri"</string>
+    <string name="menu_settings" msgid="8239065133341597825">"Yaddaş ayarları"</string>
     <string name="menu_open" msgid="432922957274920903">"Açın"</string>
     <string name="menu_save" msgid="2394743337684426338">"Yadda saxlayın"</string>
     <string name="menu_share" msgid="3075149983979628146">"Paylaşın"</string>
@@ -53,7 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Kökləri gizlədin"</string>
     <string name="save_error" msgid="6167009778003223664">"Sənədi yadda saxlaya bilmədi"</string>
     <string name="create_error" msgid="3735649141335444215">"Qovluq yaradıla bilmədi"</string>
-    <string name="query_error" msgid="5999895349602476581">"Məzmun hal-hazırda yüklənmir"</string>
+    <string name="query_error" msgid="5999895349602476581">"Məzmun hazırda yüklənmir"</string>
     <string name="root_recent" msgid="4470053704320518133">"Son"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ödənişsiz"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Saxlama xidmətləri"</string>
diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
index 40e4a07..1e1a2f7 100644
--- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Sakrij osnovne elemente"</string>
     <string name="save_error" msgid="6167009778003223664">"Čuvanje dokumenta nije uspelo"</string>
     <string name="create_error" msgid="3735649141335444215">"Direktorijum nije napravljen"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Učitavanje sadržaja trenutno nije moguće"</string>
     <string name="root_recent" msgid="4470053704320518133">"Nedavno"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Slobodno je <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Usluge skladištenja"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Još aplikacija"</string>
     <string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
     <string name="no_results" msgid="6622510343880730446">"Nema podudaranja u %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Otvaranje datoteke nije uspelo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
     <string name="share_via" msgid="8966594246261344259">"Delite preko"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datoteka"</string>
@@ -89,15 +87,25 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Priprema se kopiranje…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Priprema se premeštanje..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Priprema se brisanje…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku</item>
+      <item quantity="few">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
+      <item quantity="other">Nismo uspeli da kopiramo <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+      <item quantity="few">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+      <item quantity="other">Premeštanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije uspelo</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+      <item quantity="few">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nije uspelo</item>
+      <item quantity="other">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije uspelo</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite da biste prikazali detalje"</string>
     <string name="close" msgid="3043722427445528732">"Zatvori"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Sledeće datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Sledeće datoteke nisu premeštene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ove datoteke su konvertovane u drugi format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">Kopirali ste <xliff:g id="COUNT_1">%1$d</xliff:g> datoteku u privremenu memoriju.</item>
diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
index e87a824..f53cfa8 100644
--- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml
+++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"রুটগুলি লুকান"</string>
     <string name="save_error" msgid="6167009778003223664">"দস্তাবেজ সংরক্ষণ করতে ব্যর্থ হয়েছে"</string>
     <string name="create_error" msgid="3735649141335444215">"ফোল্ডার তৈরি করতে ব্যর্থ হয়েছে"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"এই মুহূর্তে সামগ্রী লোড করা যাবে না"</string>
     <string name="root_recent" msgid="4470053704320518133">"সাম্প্রতিক"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> খালি আছে"</string>
     <string name="root_type_service" msgid="2178854894416775409">"সঞ্চয়স্থান পরিষেবাগুলি"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"আরো অ্যাপ্লিকেশান"</string>
     <string name="empty" msgid="7858882803708117596">"কোনো আইটেম নেই"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s এ কোনো মিল নেই"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"ফাইল খোলা যাবে না"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"কিছু দস্তাবেজ মুছতে অসমর্থ"</string>
     <string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে শেয়ার করুন"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"ফাইলগুলি অনুলিপি করা হচ্ছে"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"সরানোর জন্য প্রস্তুত হচ্ছে..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"মোছার জন্য প্রস্তুত করা হচ্ছে..."</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল প্রতিলিপি করা গেল না</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল প্রতিলিপি করা গেল না</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো গেল না</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো গেল না</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা গেল না</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা গেল না</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"বিশদ বিবরণ দেখতে আলতো চাপুন"</string>
     <string name="close" msgid="3043722427445528732">"বন্ধ করুন"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"এই ফাইলগুলির প্রতিলিপি করা হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"এই ফাইলগুলি সরানো হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"এই ফাইলগুলি অন্য ফরম্যাটে রূপান্তর করা হয়েছে: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল ক্লিপবোর্ডে প্রতিলিপি করা হয়েছে।</item>
diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
index 9c7b71a..d315166 100644
--- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml
+++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml
@@ -16,136 +16,106 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for app_label (2783841764617238354) -->
-    <skip />
-    <!-- no translation found for files_label (6051402950202690279) -->
-    <skip />
-    <!-- no translation found for downloads_label (959113951084633612) -->
-    <skip />
-    <!-- no translation found for title_open (4353228937663917801) -->
-    <skip />
-    <!-- no translation found for title_save (2433679664882857999) -->
-    <skip />
-    <!-- no translation found for menu_create_dir (2547620241173881754) -->
-    <skip />
-    <!-- no translation found for menu_grid (6878021334497835259) -->
-    <skip />
-    <!-- no translation found for menu_list (7279285939892417279) -->
-    <skip />
-    <!-- no translation found for menu_sort (7677740407158414452) -->
-    <skip />
-    <!-- no translation found for menu_search (3816712084502856974) -->
-    <skip />
+    <string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
+    <string name="files_label" msgid="6051402950202690279">"Fajlovi"</string>
+    <string name="downloads_label" msgid="959113951084633612">"Preuzimanja"</string>
+    <string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
+    <string name="title_save" msgid="2433679664882857999">"Sačuvaj u"</string>
+    <string name="menu_create_dir" msgid="2547620241173881754">"Nova fascikla"</string>
+    <string name="menu_grid" msgid="6878021334497835259">"Prikaz u vidu mreže"</string>
+    <string name="menu_list" msgid="7279285939892417279">"Prikaz u vidu liste"</string>
+    <string name="menu_sort" msgid="7677740407158414452">"Sortiraj po"</string>
+    <string name="menu_search" msgid="3816712084502856974">"Traži"</string>
     <string name="menu_settings" msgid="8239065133341597825">"Postavke pohrane"</string>
-    <!-- no translation found for menu_open (432922957274920903) -->
-    <skip />
-    <!-- no translation found for menu_save (2394743337684426338) -->
-    <skip />
-    <!-- no translation found for menu_share (3075149983979628146) -->
-    <skip />
-    <!-- no translation found for menu_delete (8138799623850614177) -->
-    <skip />
-    <!-- no translation found for menu_select_all (8323579667348729928) -->
-    <skip />
-    <!-- no translation found for menu_copy (3612326052677229148) -->
-    <skip />
-    <!-- no translation found for menu_move (1828090633118079817) -->
-    <skip />
-    <!-- no translation found for menu_new_window (1226032889278727538) -->
-    <skip />
-    <!-- no translation found for menu_copy_to_clipboard (489311381979634291) -->
-    <skip />
-    <!-- no translation found for menu_paste_from_clipboard (2071583031180257091) -->
-    <skip />
-    <!-- no translation found for menu_advanced_show (4693652895715631401) -->
-    <skip />
-    <!-- no translation found for menu_advanced_hide (4218809952721972589) -->
-    <skip />
-    <!-- no translation found for menu_file_size_show (3240323619260823076) -->
-    <skip />
-    <!-- no translation found for menu_file_size_hide (8881975928502581042) -->
-    <skip />
-    <!-- no translation found for button_select (527196987259139214) -->
-    <skip />
-    <!-- no translation found for button_copy (8706475544635021302) -->
-    <skip />
-    <!-- no translation found for button_move (2202666023104202232) -->
-    <skip />
-    <!-- no translation found for button_dismiss (3714065566893946085) -->
-    <skip />
-    <!-- no translation found for button_retry (4392027584153752797) -->
-    <skip />
-    <!-- no translation found for sort_name (9183560467917256779) -->
-    <skip />
-    <!-- no translation found for sort_date (586080032956151448) -->
-    <skip />
-    <!-- no translation found for sort_size (3350681319735474741) -->
-    <skip />
-    <!-- no translation found for drawer_open (4545466532430226949) -->
-    <skip />
-    <!-- no translation found for drawer_close (7602734368552123318) -->
-    <skip />
-    <!-- no translation found for save_error (6167009778003223664) -->
-    <skip />
-    <!-- no translation found for create_error (3735649141335444215) -->
-    <skip />
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
-    <!-- no translation found for root_recent (4470053704320518133) -->
-    <skip />
-    <!-- no translation found for root_available_bytes (8568452858617033281) -->
-    <skip />
-    <!-- no translation found for root_type_service (2178854894416775409) -->
-    <skip />
-    <!-- no translation found for root_type_shortcut (3318760609471618093) -->
-    <skip />
-    <!-- no translation found for root_type_device (7121342474653483538) -->
-    <skip />
-    <!-- no translation found for root_type_apps (8838065367985945189) -->
-    <skip />
-    <!-- no translation found for empty (7858882803708117596) -->
-    <skip />
+    <string name="menu_open" msgid="432922957274920903">"Otvori"</string>
+    <string name="menu_save" msgid="2394743337684426338">"Sačuvaj"</string>
+    <string name="menu_share" msgid="3075149983979628146">"Podijeli"</string>
+    <string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
+    <string name="menu_select_all" msgid="8323579667348729928">"Odaberi sve"</string>
+    <string name="menu_copy" msgid="3612326052677229148">"Kopiraj na..."</string>
+    <string name="menu_move" msgid="1828090633118079817">"Premjesti u..."</string>
+    <string name="menu_new_window" msgid="1226032889278727538">"Novi prozor"</string>
+    <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
+    <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Zalijepi"</string>
+    <string name="menu_advanced_show" msgid="4693652895715631401">"Pokaži internu pohranu"</string>
+    <string name="menu_advanced_hide" msgid="4218809952721972589">"Sakrij internu pohranu"</string>
+    <string name="menu_file_size_show" msgid="3240323619260823076">"Pokaži veličinu fajla"</string>
+    <string name="menu_file_size_hide" msgid="8881975928502581042">"Sakrij veličinu fajla"</string>
+    <string name="button_select" msgid="527196987259139214">"Odaberi"</string>
+    <string name="button_copy" msgid="8706475544635021302">"Kopiraj"</string>
+    <string name="button_move" msgid="2202666023104202232">"Premjesti"</string>
+    <string name="button_dismiss" msgid="3714065566893946085">"Odbaci"</string>
+    <string name="button_retry" msgid="4392027584153752797">"Pokušajte ponovo"</string>
+    <string name="sort_name" msgid="9183560467917256779">"Po nazivu"</string>
+    <string name="sort_date" msgid="586080032956151448">"Po datumu izmjene"</string>
+    <string name="sort_size" msgid="3350681319735474741">"Po veličini"</string>
+    <string name="drawer_open" msgid="4545466532430226949">"Pokaži korijeni"</string>
+    <string name="drawer_close" msgid="7602734368552123318">"Sakrij korijenske foldere"</string>
+    <string name="save_error" msgid="6167009778003223664">"Pohranjivanje dokumenta nije uspjelo"</string>
+    <string name="create_error" msgid="3735649141335444215">"Kreiranje mape nije uspjelo"</string>
+    <string name="query_error" msgid="5999895349602476581">"Trenutno nije moguće učitati sadržaj"</string>
+    <string name="root_recent" msgid="4470053704320518133">"Nedavni"</string>
+    <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> slobodno"</string>
+    <string name="root_type_service" msgid="2178854894416775409">"Usluge pohranjivanja"</string>
+    <string name="root_type_shortcut" msgid="3318760609471618093">"Prečice"</string>
+    <string name="root_type_device" msgid="7121342474653483538">"Uređaji"</string>
+    <string name="root_type_apps" msgid="8838065367985945189">"Više aplikacija"</string>
+    <string name="empty" msgid="7858882803708117596">"Nema stavki"</string>
     <string name="no_results" msgid="6622510343880730446">"Nema rezultata u %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
-    <!-- no translation found for toast_failed_delete (2180678019407244069) -->
-    <skip />
-    <!-- no translation found for share_via (8966594246261344259) -->
-    <skip />
-    <!-- no translation found for copy_notification_title (6374299806748219777) -->
-    <skip />
-    <!-- no translation found for move_notification_title (6193835179777284805) -->
-    <skip />
-    <!-- no translation found for copy_remaining (6283790937387975095) -->
-    <skip />
-    <!-- no translation found for copy_begin (9071199452634086365) -->
-    <!-- no translation found for move_begin (8430330882138871643) -->
-    <!-- no translation found for deleting (5054338566802559411) -->
-    <!-- no translation found for undo (7905788502491742328) -->
-    <skip />
-    <!-- no translation found for copy_preparing (3896202461003039386) -->
-    <skip />
-    <!-- no translation found for move_preparing (2772219441375531410) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Nije moguće otvoriti fajl"</string>
+    <string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće obrisati neke dokumente"</string>
+    <string name="share_via" msgid="8966594246261344259">"Podijeli preko"</string>
+    <string name="copy_notification_title" msgid="6374299806748219777">"Kopiraju se fajlovi"</string>
+    <string name="move_notification_title" msgid="6193835179777284805">"Premještanje fajlova"</string>
+    <string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
+    <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+      <item quantity="one">Kopira se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+      <item quantity="few">Kopiraju se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+      <item quantity="other">Kopira se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+    </plurals>
+    <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+      <item quantity="one">Premješta se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+      <item quantity="few">Premještaju se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+      <item quantity="other">Premješta se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+    </plurals>
+    <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+      <item quantity="one">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> fajl.</item>
+      <item quantity="few">Brišu se <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item>
+      <item quantity="other">Briše se <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item>
+    </plurals>
+    <string name="undo" msgid="7905788502491742328">"Vrati"</string>
+    <string name="copy_preparing" msgid="3896202461003039386">"Priprema se kopiranje..."</string>
+    <string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Pripremanje za brisanje…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+      <item quantity="few">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+      <item quantity="other">Nije moguće kopirati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+      <item quantity="few">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+      <item quantity="other">Nije moguće premjestiti <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajl</item>
+      <item quantity="few">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla</item>
+      <item quantity="other">Nije moguće izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Dodirnite za prikaz detalja"</string>
     <string name="close" msgid="3043722427445528732">"Zatvori"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Nisu kopirani sljedeći fajlovi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Nisu premješteni sljedeći fajlovi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ove datoteke su pretvorene u drugi format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
-    <!-- no translation found for clipboard_files_clipped (855459017537058539) -->
-    <!-- no translation found for clipboard_files_cannot_paste (2878324825602325706) -->
-    <skip />
+    <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fajl je kopiran u međuspremnik.</item>
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> fajla su kopirana u međuspremnik.</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fajlova je kopirano u međuspremnik.</item>
+    </plurals>
+    <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Odabrani fajlovi se ne mogu zalijepiti na ovu lokaciju."</string>
     <string name="menu_rename" msgid="7678802479104285353">"Preimenuj"</string>
     <string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string>
     <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke od datoteka su pretvorene"</string>
-    <!-- no translation found for allow (7225948811296386551) -->
-    <skip />
-    <!-- no translation found for deny (2081879885755434506) -->
-    <skip />
+    <string name="allow" msgid="7225948811296386551">"Dozvoli"</string>
+    <string name="deny" msgid="2081879885755434506">"Odbijte"</string>
 </resources>
diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
index 2cb22c8..96bfbb7 100644
--- a/packages/DocumentsUI/res/values-ca/strings.xml
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Amaga les arrels"</string>
     <string name="save_error" msgid="6167009778003223664">"No s\'ha pogut desar el document."</string>
     <string name="create_error" msgid="3735649141335444215">"No s\'ha pogut crear la carpeta"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"En aquest moment no es pot carregar el contingut"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recent"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> lliures"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Serveis d\'emmagatzematge"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Més aplicacions"</string>
     <string name="empty" msgid="7858882803708117596">"Sense elements"</string>
     <string name="no_results" msgid="6622510343880730446">"No hi ha cap coincidència a %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"No es pot obrir el fitxer"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
     <string name="share_via" msgid="8966594246261344259">"Comparteix mitjançant"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"S\'estan copiant fitxers"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"S\'està preparant una còpia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"S\'està preparant per moure\'ls..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"S\'està preparant per suprimir…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">No s\'han pogut copiar <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
+      <item quantity="one">No s\'ha pogut copiar <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">No s\'han pogut moure <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
+      <item quantity="one">No s\'ha pogut moure <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">No s\'han pogut suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
+      <item quantity="one">No s\'ha pogut suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Toca per veure\'n els detalls"</string>
     <string name="close" msgid="3043722427445528732">"Tanca"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Aquests fitxers no s\'han mogut: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Aquests fitxers s\'han convertit a un altre format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">S\'han copiat <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers al porta-retalls.</item>
diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml
index c41b1b1..a6e79b6 100644
--- a/packages/DocumentsUI/res/values-cs/strings.xml
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Skrýt kořeny"</string>
     <string name="save_error" msgid="6167009778003223664">"Uložení dokumentu se nezdařilo"</string>
     <string name="create_error" msgid="3735649141335444215">"Složku se nepodařilo vytvořit"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Obsah nyní nelze načíst"</string>
     <string name="root_recent" msgid="4470053704320518133">"Nedávné"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Volné místo: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Služby úložiště"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Další aplikace"</string>
     <string name="empty" msgid="7858882803708117596">"Žádné položky"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s – žádné shody"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Soubor nelze otevřít"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
     <string name="share_via" msgid="8966594246261344259">"Sdílet pomocí"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopírování souborů"</string>
@@ -92,15 +90,28 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Příprava na kopírování…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Příprava na přesunutí…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Příprava na mazání…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory se zkopírovat nepodařilo</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru se zkopírovat nepodařilo</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů se zkopírovat nepodařilo</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor se zkopírovat nepodařilo</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory nelze přesunout</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru nelze přesunout</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů nelze přesunout</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor nelze přesunout</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory se smazat nepodařilo</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru se smazat nepodařilo</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů se smazat nepodařilo</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor se smazat nepodařilo</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Klepnutím zobrazíte podrobnosti"</string>
     <string name="close" msgid="3043722427445528732">"Zavřít"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Následující soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Následující soubory nebyly přesunuty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Soubory byly převedeny do jiného formátu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory byly zkopírovány do schránky.</item>
diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml
index 78c59b9..a0b7c1f 100644
--- a/packages/DocumentsUI/res/values-da/strings.xml
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Skjul rødder"</string>
     <string name="save_error" msgid="6167009778003223664">"Dokumentet kunne ikke gemmes"</string>
     <string name="create_error" msgid="3735649141335444215">"Mappen kunne ikke oprettes"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Der kan ikke indlæses indhold i øjeblikket"</string>
     <string name="root_recent" msgid="4470053704320518133">"Seneste"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig plads"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Flere apps"</string>
     <string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
     <string name="no_results" msgid="6622510343880730446">"Ingen kampe i %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Filen kan ikke åbnes"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
     <string name="share_via" msgid="8966594246261344259">"Del via"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytning…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Forbereder til sletning…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke kopieres</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke kopieres</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke flyttes</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke flyttes</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fil kunne ikke slettes</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer kunne ikke slettes</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Tryk for at se oplysninger"</string>
     <string name="close" msgid="3043722427445528732">"Luk"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Disse filer blev ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Disse filer er konverteret til et andet format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev kopieret til udklipsholder.</item>
diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml
index fb25867..2d968fe 100644
--- a/packages/DocumentsUI/res/values-de/strings.xml
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Root-Verzeichnis ausblenden"</string>
     <string name="save_error" msgid="6167009778003223664">"Dokument konnte nicht gespeichert werden."</string>
     <string name="create_error" msgid="3735649141335444215">"Ordner konnte nicht erstellt werden."</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Inhalte können momentan nicht geladen werden"</string>
     <string name="root_recent" msgid="4470053704320518133">"Letzte"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> verfügbar"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Speicherdienste"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Weitere Apps"</string>
     <string name="empty" msgid="7858882803708117596">"Keine Dokumente"</string>
     <string name="no_results" msgid="6622510343880730446">"Keine Übereinstimmungen in %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Datei kann nicht geöffnet werden"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
     <string name="share_via" msgid="8966594246261344259">"Teilen über"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Dateien werden kopiert"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Kopieren wird vorbereitet…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Verschieben wird vorbereitet…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Löschvorgang wird vorbereitet…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht kopiert werden</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht kopiert werden</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht verschoben werden</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht verschoben werden</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht gelöscht werden</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht gelöscht werden</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Zum Ansehen der Details tippen"</string>
     <string name="close" msgid="3043722427445528732">"Schließen"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Diese Dateien wurden nicht verschoben: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Folgende Dateien wurden in ein anderes Format konvertiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien wurden in die Zwischenablage kopiert.</item>
diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml
index 5661e82..6c9896d 100644
--- a/packages/DocumentsUI/res/values-el/strings.xml
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Απόκρυψη ρίζας"</string>
     <string name="save_error" msgid="6167009778003223664">"Αποτυχία αποθήκευσης του εγγράφου"</string>
     <string name="create_error" msgid="3735649141335444215">"Αποτυχία δημιουργίας φακέλου"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Δεν είναι δυνατή η φόρτωση περιεχομένου τώρα"</string>
     <string name="root_recent" msgid="4470053704320518133">"Πρόσφατα"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ελεύθερα"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Υπηρεσίες αποθήκευσης"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Περισσότερες εφαρμογές"</string>
     <string name="empty" msgid="7858882803708117596">"Δεν υπάρχουν στοιχεία"</string>
     <string name="no_results" msgid="6622510343880730446">"Χωρίς αντιστοιχίσεις στο %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Δεν είναι δυνατό το άνοιγμα του αρχείου"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
     <string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Αντιγραφή αρχείων"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Προετοιμασία για μετακίνηση…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Προετοιμασία για διαγραφή…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
+      <item quantity="one">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
+      <item quantity="one">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Δεν ήταν δυνατή η διαγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
+      <item quantity="one">Δεν ήταν δυνατή η διαγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Πατήστε για προβολή λεπτομερειών"</string>
     <string name="close" msgid="3043722427445528732">"Κλείσιμο"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Αυτά τα αρχεία δεν μετακινήθηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Αυτά τα αρχεία μετατράπηκαν σε άλλη μορφή: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> αρχεία αντιγράφηκαν στο πρόχειρο.</item>
diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml
index a729732..e212053 100644
--- a/packages/DocumentsUI/res/values-es-rUS/strings.xml
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
     <string name="save_error" msgid="6167009778003223664">"Error al guardar el documento"</string>
     <string name="create_error" msgid="3735649141335444215">"Error al crear la carpeta"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"No se puede cargar el contenido en este momento"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recientes"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> de espacio libre"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Almacenamiento"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
     <string name="empty" msgid="7858882803708117596">"Sin elementos"</string>
     <string name="no_results" msgid="6622510343880730446">"No hay coincidencias en %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"No se puede abrir el archivo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
     <string name="share_via" msgid="8966594246261344259">"Compartir mediante"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparación para mover archivos…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Preparando para borrar…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">No se pudo copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">No se pudieron trasladar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">No se pudo trasladar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">No se pudieron borrar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+      <item quantity="one">No se pudo borrar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Presiona para ver los detalles"</string>
     <string name="close" msgid="3043722427445528732">"Cerrar"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Los siguientes archivos no se pudieron copiar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Los siguientes archivos no se trasladaron: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Estos archivos se convirtieron a otro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">Se copiaron <xliff:g id="COUNT_1">%1$d</xliff:g> archivos al portapapeles.</item>
diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml
index 539774f..a8f3517 100644
--- a/packages/DocumentsUI/res/values-eu-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ezkutatu erroko karpetak"</string>
     <string name="save_error" msgid="6167009778003223664">"Ezin izan da dokumentua gorde"</string>
     <string name="create_error" msgid="3735649141335444215">"Ezin izan da karpeta sortu"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Une honetan ezin da kargatu edukia"</string>
     <string name="root_recent" msgid="4470053704320518133">"Azkenak"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> doan"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Biltegiratze-zerbitzuak"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Aplikazio gehiago"</string>
     <string name="empty" msgid="7858882803708117596">"Ez dago elementurik"</string>
     <string name="no_results" msgid="6622510343880730446">"Ez da aurkitu ezer %1$s atalean"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Ezin da ireki fitxategia"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ezin izan dira dokumentu batzuk ezabatu"</string>
     <string name="share_via" msgid="8966594246261344259">"Partekatu honen bidez:"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Fitxategiak kopiatzen"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Kopiatzeko prestatzen…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Mugitzeko prestatzen…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Ezabatzeko prestatzen…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Ezin izan dira kopiatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
+      <item quantity="one">Ezin izan da kopiatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Ezin izan dira mugitu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
+      <item quantity="one">Ezin izan da mugitu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Ezin izan dira ezabatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
+      <item quantity="one">Ezin izan da ezabatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Sakatu xehetasunak ikusteko"</string>
     <string name="close" msgid="3043722427445528732">"Itxi"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Ez dira mugitu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Fitxategi hauek beste formatu bateko fitxategi bihurtu dira: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatu dira arbelean.</item>
diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
index e349eef..14513bd 100644
--- a/packages/DocumentsUI/res/values-fi/strings.xml
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Piilota juuret"</string>
     <string name="save_error" msgid="6167009778003223664">"Asiakirjan tallennus epäonnistui"</string>
     <string name="create_error" msgid="3735649141335444215">"Kansion luominen epäonnistui"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Sisältöä ei juuri nyt voi ladata."</string>
     <string name="root_recent" msgid="4470053704320518133">"Viimeisimmät"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> vapaana"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Tallennuspalvelut"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Lisää sovelluksia"</string>
     <string name="empty" msgid="7858882803708117596">"Ei kohteita"</string>
     <string name="no_results" msgid="6622510343880730446">"Ei osumia kohteessa %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Tiedoston avaaminen epäonnistui."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
     <string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopioidaan tiedostoja"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Valmistellaan kopiointia…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Valmistellaan siirtämistä…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Valmistellaan poistamista…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston poistaminen epäonnistui.</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston poistaminen epäonnistui.</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Tarkastele tietoja napauttamalla"</string>
     <string name="close" msgid="3043722427445528732">"Sulje"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Näitä tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Näitä tiedostoja ei siirretty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Seuraavat tiedostot muunnettiin toiseen muotoon: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa kopioitiin leikepöydälle.</item>
diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
index fad4800..0d35f4a 100644
--- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Masquer les racines"</string>
     <string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document"</string>
     <string name="create_error" msgid="3735649141335444215">"Échec de la création du dossier"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Impossible de charger le contenu pour le moment"</string>
     <string name="root_recent" msgid="4470053704320518133">"Récents"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> disponible"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Services de stockage"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Plus d\'applications"</string>
     <string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
     <string name="no_results" msgid="6622510343880730446">"Aucune correspondance dans %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Impossible d\'ouvrir le fichier"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
     <string name="share_via" msgid="8966594246261344259">"Partager par"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers..."</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Préparation du déplacement..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Préparation de la suppression..."</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossier</item>
+      <item quantity="other">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> dossiers</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Touchez pour afficher les détails"</string>
     <string name="close" msgid="3043722427445528732">"Fermer"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Ces fichiers n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ces fichiers ont été convertis dans un autre format : <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a été copié dans le presse-papiers.</item>
diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml
index 413416b..7ed98bb 100644
--- a/packages/DocumentsUI/res/values-fr/strings.xml
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Masquer les répertoires racines"</string>
     <string name="save_error" msgid="6167009778003223664">"Échec de l\'enregistrement du document."</string>
     <string name="create_error" msgid="3735649141335444215">"Échec de la création du dossier."</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Impossible de charger le contenu pour le moment"</string>
     <string name="root_recent" msgid="4470053704320518133">"Récents"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Espace disponible : <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Services de stockage"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Autres applications"</string>
     <string name="empty" msgid="7858882803708117596">"Aucun élément"</string>
     <string name="no_results" msgid="6622510343880730446">"Aucune correspondance dans %1$s."</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Impossible d\'ouvrir le fichier"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
     <string name="share_via" msgid="8966594246261344259">"Partager via"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers en cours"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Préparation au déplacement…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Préparation à la suppression…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+      <item quantity="other">Impossible de supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Appuyez pour afficher plus d\'informations."</string>
     <string name="close" msgid="3043722427445528732">"Fermer"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Les fichiers suivants n\'ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Les fichiers suivants n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ces fichiers ont été convertis dans un autre format : <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a bien été copié dans le Presse-papiers.</item>
diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml
index 3274568..645eb04 100644
--- a/packages/DocumentsUI/res/values-gl-rES/strings.xml
+++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ocultar raíces"</string>
     <string name="save_error" msgid="6167009778003223664">"Non se puido gardar o documento"</string>
     <string name="create_error" msgid="3735649141335444215">"Non se puido crear o cartafol"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Non se pode cargar o contido neste momento"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> libres"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Servizos de almacenamento"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Máis aplicacións"</string>
     <string name="empty" msgid="7858882803708117596">"Ningún elemento"</string>
     <string name="no_results" msgid="6622510343880730446">"Non hai coincidencias en %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Non se pode abrir o ficheiro"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Non se poden eliminar algúns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copiando ficheiros"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparándose para mover..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Preparando para eliminar…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Non se puideron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Non se puido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Non se puideron mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Non se puido mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Non se puideron eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Non se puido eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Toca para ver detalles"</string>
     <string name="close" msgid="3043722427445528732">"Pechar"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Non se moveron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Estes ficheiros convertéronse a outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">Copiáronse <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros no portapapeis.</item>
diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
index 39344de..4448fe4 100644
--- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Թաքցնել արմատները"</string>
     <string name="save_error" msgid="6167009778003223664">"Չհաջողվեց պահել փաստաթուղթը"</string>
     <string name="create_error" msgid="3735649141335444215">"Չհաջողվեց ստեղծել պանակը"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Այս պահին հնարավոր չէ բեռնել բովանդակությունը"</string>
     <string name="root_recent" msgid="4470053704320518133">"Վերջին"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ազատ է"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Պահուստի ծառայություններ"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Հավելյալ ծրագրեր"</string>
     <string name="empty" msgid="7858882803708117596">"Տարրեր չկան"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s-ում համընկնումներ չկան"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Հնարավոր չէ բացել ֆայլը"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
     <string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Ֆայլերի պատճենում"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Տեղափոխման նախապատրաստում…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Պատրաստվում է ջնջել…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+      <item quantity="other">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+      <item quantity="other">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Չհաջողվեց ջնջել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+      <item quantity="other">Չհաջողվեց ջնջել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Հպեք՝ մանրամասները դիտելու համար"</string>
     <string name="close" msgid="3043722427445528732">"Փակել"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Հետևյալ ֆայլերը չեն տեղափոխվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Այս ֆայլերը փոխարկվել են մեկ այլ ձևաչափի՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ պատճենվեց սեղմատախտակին:</item>
diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml
index 1d3d75f..d7e4284 100644
--- a/packages/DocumentsUI/res/values-is-rIS/strings.xml
+++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Fela rótarsöfn"</string>
     <string name="save_error" msgid="6167009778003223664">"Mistókst að vista skjalið"</string>
     <string name="create_error" msgid="3735649141335444215">"Mistókst að búa til möppu"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Ekki hægt að hlaða efni í augnablikinu"</string>
     <string name="root_recent" msgid="4470053704320518133">"Nýlegt"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> laus"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Geymsluþjónusta"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Fleiri forrit"</string>
     <string name="empty" msgid="7858882803708117596">"Engin atriði"</string>
     <string name="no_results" msgid="6622510343880730446">"Engar samsvarandi niðurstöður í %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Ekki hægt að opna skrá"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ekki er hægt að eyða einhverjum skjölum"</string>
     <string name="share_via" msgid="8966594246261344259">"Deila í gegnum"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Afritar skrár"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Undirbúningur fyrir afritun…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Flutningur undirbúinn…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Býr sig undir að eyða…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Ekki tókst að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+      <item quantity="other">Ekki tókst að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+      <item quantity="other">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Ekki tókst að eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+      <item quantity="other">Ekki tókst að eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrám</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Ýttu til að skoða frekari upplýsingar"</string>
     <string name="close" msgid="3043722427445528732">"Loka"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Þessar skrár voru ekki færðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Þessum skrám var umbreytt yfir á annað snið: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> skrá afrituð á klippiborð.</item>
diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml
index e0f750a..8806079 100644
--- a/packages/DocumentsUI/res/values-iw/strings.xml
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"הסתר שורשים"</string>
     <string name="save_error" msgid="6167009778003223664">"שמירת המסמך נכשלה"</string>
     <string name="create_error" msgid="3735649141335444215">"יצירת התיקיה נכשלה"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"לא ניתן כרגע לטעון תוכן"</string>
     <string name="root_recent" msgid="4470053704320518133">"מהזמן האחרון"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> של שטח פנוי"</string>
     <string name="root_type_service" msgid="2178854894416775409">"שירותי אחסון"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"עוד אפליקציות"</string>
     <string name="empty" msgid="7858882803708117596">"אין פריטים"</string>
     <string name="no_results" msgid="6622510343880730446">"‏אין התאמות ב-%1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"לא ניתן לפתוח את הקובץ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
     <string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"מעתיק קבצים"</string>
@@ -92,15 +90,28 @@
     <string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"מתכונן להעברה…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"מתכונן למחיקה…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="two">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="many">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="other">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="one">לא ניתן היה להעתיק <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="two">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="many">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="other">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="one">לא ניתן היה להעביר <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="two">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="many">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="other">לא ניתן היה למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+      <item quantity="one">לא ניתן היה למחוק <xliff:g id="COUNT_0">%1$d</xliff:g> קובץ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"הקש כדי להציג פרטים"</string>
     <string name="close" msgid="3043722427445528732">"סגור"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"הקבצים הבאים לא הועתקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"הקבצים הבאים לא הועברו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"הקבצים האלה הומרו לפורמט אחר: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> קבצים הועתקו אל הלוח.</item>
diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
index c56876d..e0b82e5 100644
--- a/packages/DocumentsUI/res/values-ja/strings.xml
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ルートを非表示にする"</string>
     <string name="save_error" msgid="6167009778003223664">"ドキュメントを保存できませんでした"</string>
     <string name="create_error" msgid="3735649141335444215">"フォルダを作成できませんでした"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"現在、コンテンツを読み込むことができません"</string>
     <string name="root_recent" msgid="4470053704320518133">"最近"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"空き容量: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"ストレージサービス"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"その他のアプリ"</string>
     <string name="empty" msgid="7858882803708117596">"アイテムがありません"</string>
     <string name="no_results" msgid="6622510343880730446">"該当するものは %1$s にありません"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"ファイルを開けません"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
     <string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"ファイルのコピー中"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"移動の準備をしています…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"削除の準備をしています…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルをコピーできませんでした</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルをコピーできませんでした</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを移動できませんでした</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを移動できませんでした</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを削除できませんでした</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを削除できませんでした</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"タップすると詳細が表示されます"</string>
     <string name="close" msgid="3043722427445528732">"閉じる"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"次のファイルをコピーできませんでした: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"次のファイルを移動できませんでした: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"次のファイルが別の形式に変換されました: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件のファイルをクリップボードにコピーしました。</item>
diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
index 69ffda2..5e1ddd3 100644
--- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ფესვების დამალვა"</string>
     <string name="save_error" msgid="6167009778003223664">"დოკუმენტის შენახვა ვერ მოხერხდა"</string>
     <string name="create_error" msgid="3735649141335444215">"საქაღალდის შექმნა ვერ მოხერხდა"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"კონტენტის ჩატვირთვა ამჟამად ვერ ხერხდება"</string>
     <string name="root_recent" msgid="4470053704320518133">"ბოლო"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> თავისუფალია"</string>
     <string name="root_type_service" msgid="2178854894416775409">"მეხსიერების სერვისები"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"მეტი აპები"</string>
     <string name="empty" msgid="7858882803708117596">"ერთეულები არ არის"</string>
     <string name="no_results" msgid="6622510343880730446">"„%1$s“-ში დამთხვევა ვერ მოიძებნა"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"ფაილის გახსნა ვერ ხერხდება"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
     <string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"მიმდ. ფაილების კოპირება"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"მომზადება კოპირებისთვის…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"გადაადგილება მზადდება..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"მზადდება წასაშლელად…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ დაკოპირდა</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ დაკოპირდა</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ წაიშალა</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ წაიშალა</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"შეეხეთ დეტალების სანახავად"</string>
     <string name="close" msgid="3043722427445528732">"დახურვა"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"შემდეგი ფაილები არ დაკოპირდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"შემდეგი ფაილები არ გადაადგილდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"შემდეგი ფაილები გარდაქმნილია სხვა ფორმატში: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">მოხდა <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის გაცვლის ბუფერში კოპირება.</item>
diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
index a6a3876..5b6b94d 100644
--- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
+++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml
@@ -53,7 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Тамырын жасыру"</string>
     <string name="save_error" msgid="6167009778003223664">"Құжатты сақтау орындалмады"</string>
     <string name="create_error" msgid="3735649141335444215">"Қалта жасақтау іске аспады"</string>
-    <string name="query_error" msgid="5999895349602476581">"Қазіргі уақытта мазмұнды жүктеу мүмкін емес"</string>
+    <string name="query_error" msgid="5999895349602476581">"Қазір мазмұнды жүктеу мүмкін емес"</string>
     <string name="root_recent" msgid="4470053704320518133">"Жуықта қолданылған"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> бос"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Жад қызметтері"</string>
diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
index 9c956f5..487a7b3 100644
--- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ರೂಟ್‌ಗಳನ್ನು ಮರೆಮಾಡು"</string>
     <string name="save_error" msgid="6167009778003223664">"ಡಾಕ್ಯುಮೆಂಟ್ ಉಳಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
     <string name="create_error" msgid="3735649141335444215">"ಫೋಲ್ಡರ್ ರಚಿಸಲು ವಿಫಲವಾಗಿದೆ"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"ಈ ಕ್ಷಣದಲ್ಲಿ ವಿಷಯವನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="root_recent" msgid="4470053704320518133">"ಇತ್ತೀಚಿನದು"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ಮುಕ್ತವಾಗಿದೆ"</string>
     <string name="root_type_service" msgid="2178854894416775409">"ಸಂಗ್ರಹಣೆ ಸೇವೆಗಳು"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"ಇನ್ನಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
     <string name="empty" msgid="7858882803708117596">"ಯಾವುದೇ ಐಟಂಗಳಿಲ್ಲ"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s ರಲ್ಲಿ ಯಾವುದೇ ಹೊಂದಾಣಿಕೆಗಳಿಲ್ಲ"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"ಫೈಲ್ ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="share_via" msgid="8966594246261344259">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"ಅಳಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="close" msgid="3043722427445528732">"ಮುಚ್ಚು"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"ಈ ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಸರಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"ಈ ಫೈಲ್‌ಗಳನ್ನು ಮತ್ತೊಂದು ಫಾರ್ಮೆಟ್‌ಗೆ ಪರಿವರ್ತಿಸಲಾಗಿತ್ತು: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್‌ಗಳನ್ನು ನಕಲಿಸಲಾಗಿದೆ.</item>
diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
index 1dc5e77..f93f709 100644
--- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml
+++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Папкаларды жашыруу"</string>
     <string name="save_error" msgid="6167009778003223664">"Документтерди сактоо кыйрады"</string>
     <string name="create_error" msgid="3735649141335444215">"Папка түзүү кыйрады"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Учурда мазмун жүктөлбөй жатат"</string>
     <string name="root_recent" msgid="4470053704320518133">"Акыркы"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> бош"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Сактагыч кызматтар"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Көбүрөөк колдонмолор"</string>
     <string name="empty" msgid="7858882803708117596">"Эч нерсе жок"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s ичинде дал келүүлөр жок"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Файл ачылбай жатат"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Кээ бир документтерди өчүрүү кыйрады"</string>
     <string name="share_via" msgid="8966594246261344259">"Кийинки аркылуу бөлүшүү:"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Файлдар көчүрүлүүдө"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Жылдырууга даярдалууда…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Жок кылууга даярдалууда…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлбөй койду</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлбөй койду</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жылдырылбай койду</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жылдырылбай койду</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынбай койду</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынбай койду</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Чоо-жайын көрүү үчүн таптаңыз"</string>
     <string name="close" msgid="3043722427445528732">"Жабуу"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Төмөнкү файлдар жылдырылган жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Бул файлдар башка форматка айландырылды: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл буферге көчүрүлдү.</item>
diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
index 65276ba..4b36057 100644
--- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -85,8 +85,8 @@
     <string name="move_preparing" msgid="2772219441375531410">"ກຳ​ລັງ​ກະ​ກຽມ​ຍ້າຍ…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"ກຳລັງກະກຽມລຶບ…"</string>
     <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
-      <item quantity="other">ບໍ່ສາມາດອັດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
-      <item quantity="one">ບໍ່ສາມາດອັດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
+      <item quantity="other">ບໍ່ສາມາດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
+      <item quantity="one">ບໍ່ສາມາດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
     </plurals>
     <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
       <item quantity="other">ບໍ່ສາມາດຍ້າຍ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
@@ -98,7 +98,7 @@
     </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດ"</string>
     <string name="close" msgid="3043722427445528732">"ປິດ"</string>
-    <string name="copy_failure_alert_content" msgid="4563147454522476183">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກອັດສຳເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກສຳເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="move_failure_alert_content" msgid="2635075788682922861">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກຍ້າຍ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"ໄຟລ໌ເຫຼົ່ານີ້ໄດ້ຖືກປ່ຽນເປັນຮູບແບບອື່ນແລ້ວ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml
index 224e15b..7711941 100644
--- a/packages/DocumentsUI/res/values-lv/strings.xml
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Slēpt saknes"</string>
     <string name="save_error" msgid="6167009778003223664">"Neizdevās saglabāt dokumentu."</string>
     <string name="create_error" msgid="3735649141335444215">"Neizdevās izveidot mapi."</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Pašlaik nevar ielādēt saturu."</string>
     <string name="root_recent" msgid="4470053704320518133">"Pēdējie"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Brīva vieta: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Glabāšanas pakalpojumi"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Vairāk lietotņu"</string>
     <string name="empty" msgid="7858882803708117596">"Nav vienumu"</string>
     <string name="no_results" msgid="6622510343880730446">"Failā %1$s nav atbilstību"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Nevar atvērt failu."</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
     <string name="share_via" msgid="8966594246261344259">"Kopīgot, izmantojot"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Notiek failu kopēšana"</string>
@@ -89,15 +87,25 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Gatavošanās kopēšanai…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Sagatavošana pārvietošanai…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Notiek gatavošanās dzēšanai…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="zero">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+      <item quantity="one">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+      <item quantity="other">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="zero">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+      <item quantity="one">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+      <item quantity="other">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="zero">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+      <item quantity="one">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
+      <item quantity="other">Nevarēja izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Pieskarieties, lai skatītu informāciju"</string>
     <string name="close" msgid="3043722427445528732">"Aizvērt"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Netika pārvietoti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Šie faili tika pārveidoti citā formātā: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> faili tika kopēti starpliktuvē.</item>
diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
index f24dc96..64f6163 100644
--- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
     <string name="save_error" msgid="6167009778003223664">"Gagal menyimpan dokumen"</string>
     <string name="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Tidak dapat memuatkan kandungan pada masa ini"</string>
     <string name="root_recent" msgid="4470053704320518133">"Terbaharu"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> kosong"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Perkhidmatan storan"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Lebih banyak apl"</string>
     <string name="empty" msgid="7858882803708117596">"Tiada item"</string>
     <string name="no_results" msgid="6622510343880730446">"Tiada padanan dalam %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Tidak dapat membuka fail"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
     <string name="share_via" msgid="8966594246261344259">"Kongsi melalui"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Menyalin fail"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Bersedia untuk salin..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Bersedia untuk mengalih…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Bersedia untuk memadam…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
+      <item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Tidak dapat mengalihkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
+      <item quantity="one">Tidak dapat mengalihkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Tidak dapat memadamkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
+      <item quantity="one">Tidak dapat memadamkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Ketik untuk melihat butiran"</string>
     <string name="close" msgid="3043722427445528732">"Tutup"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Fail ini tidak dialihkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Fail ini telah ditukarkan kepada format lain: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fail disalin ke papan keratan.</item>
diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml
index 74d0ae4..2813f2d 100644
--- a/packages/DocumentsUI/res/values-my-rMM/strings.xml
+++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml
@@ -53,7 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ဖိုဒါကို ပိတ်လိုက်ပါ"</string>
     <string name="save_error" msgid="6167009778003223664">"စာရွက်စာတန်း သိမ်းဆည်းမှု မအောင်​မြင်ပါ"</string>
     <string name="create_error" msgid="3735649141335444215">"အကန့်အသစ် ဖန်တီးခြင်း မအောင်မြင်ပါ"</string>
-    <string name="query_error" msgid="5999895349602476581">"အကြောင်းအရာများကို လောလောဆယ်တွင် ဖွင့်၍မရသေးပါ"</string>
+    <string name="query_error" msgid="5999895349602476581">"အကြောင်းအရာများကို လောလောဆယ်တွင် တင်၍မရသေးပါ"</string>
     <string name="root_recent" msgid="4470053704320518133">"လတ်တလော"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> အသုံးချနိုင်ပါသည်"</string>
     <string name="root_type_service" msgid="2178854894416775409">"သိုလှောင်ရန်ဆားဗစ်များ"</string>
diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml
index aa74b98..d79b279 100644
--- a/packages/DocumentsUI/res/values-nb/strings.xml
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Skjul røtter"</string>
     <string name="save_error" msgid="6167009778003223664">"Kunne ikke lagre dokumentet"</string>
     <string name="create_error" msgid="3735649141335444215">"Kunne ikke opprette mappen"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Kan ikke laste inn innholdet for øyeblikket"</string>
     <string name="root_recent" msgid="4470053704320518133">"Siste"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Flere apper"</string>
     <string name="empty" msgid="7858882803708117596">"Ingen elementer"</string>
     <string name="no_results" msgid="6622510343880730446">"Ingen treff i %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Kan ikke åpne filen"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
     <string name="share_via" msgid="8966594246261344259">"Del via"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering …"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytting …"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Gjøres klar for sletting …"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Kunne ikke kopiere <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+      <item quantity="one">Kunne ikke kopiere <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Kunne ikke flytte <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+      <item quantity="one">Kunne ikke flytte <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Kunne ikke slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+      <item quantity="one">Kunne ikke slette <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Trykk for å se detaljer"</string>
     <string name="close" msgid="3043722427445528732">"Lukk"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Disse filene er ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Disse filene er ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Disse filene er konvertert til et annet format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">Kopierte <xliff:g id="COUNT_1">%1$d</xliff:g> filer til utklippstavlen.</item>
diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
index ccc54c7..057e03f 100644
--- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml
+++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml
@@ -53,7 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"मूलहरू लुकाउनुहोस्"</string>
     <string name="save_error" msgid="6167009778003223664">"कागजात सुरक्षित गर्न विफल भयो"</string>
     <string name="create_error" msgid="3735649141335444215">"फोल्डर सिर्जना गर्न असफल भयो"</string>
-    <string name="query_error" msgid="5999895349602476581">"यो समय सामग्री लोड गर्न सक्दैन"</string>
+    <string name="query_error" msgid="5999895349602476581">"अहिले सामग्री लोड गर्न सक्दैन"</string>
     <string name="root_recent" msgid="4470053704320518133">"हालैको"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> खाली"</string>
     <string name="root_type_service" msgid="2178854894416775409">"भण्डारण सेवाहरू"</string>
@@ -62,7 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"थप अनुप्रयोगहरू"</string>
     <string name="empty" msgid="7858882803708117596">"कुनै वस्तु छैन।"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s मा कुनै पनि मेल खानेहरू छैन"</string>
-    <string name="toast_no_application" msgid="4632640357724698144">"फाइल खोल्न सकिदैन"</string>
+    <string name="toast_no_application" msgid="4632640357724698144">"फाइल खोल्न सक्दैन"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
     <string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"फाइलहरू प्रतिलिपि गर्दै:"</string>
diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
index 0fb35fa..758a4d8 100644
--- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ਰੂਟਸ ਲੁਕਾਓ"</string>
     <string name="save_error" msgid="6167009778003223664">"ਦਸਾਤਵੇਜ਼ ਸੁਰੱਖਿਅਤ ਕਰਨ ਵਿੱਚ ਅਸਫਲ"</string>
     <string name="create_error" msgid="3735649141335444215">"ਫੋਲਡਰ ਬਣਾਉਣ ਲਈ ਅਸਫਲ"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"ਇਸ ਵੇਲੇ ਸਮੱਗਰੀ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
     <string name="root_recent" msgid="4470053704320518133">"ਹਾਲੀਆ"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ਖਾਲੀ"</string>
     <string name="root_type_service" msgid="2178854894416775409">"ਸਟੋਰੇਜ ਸੇਵਾਵਾਂ"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"ਹੋਰ ਐਪਸ"</string>
     <string name="empty" msgid="7858882803708117596">"ਕੋਈ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s ਵਿੱਚ ਕੋਈ ਮੇਲ ਨਹੀਂ"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"ਫ਼ਾਈਲ ਨੂੰ ਖੋਲ੍ਹਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ਕੁਝ ਦਸਤਾਵੇਜ਼ ਮਿਟਾਉਣ ਵਿੱਚ ਅਸਮਰੱਥ"</string>
     <string name="share_via" msgid="8966594246261344259">"ਇਸ ਰਾਹੀਂ ਸ਼ੇਅਰ ਕਰੋ"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"ਕਾਪੀ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"ਮੂਵ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"ਮਿਟਾਉਣ ਦੀ ਤਿਆਰੀ ਹੋ ਰਹੀ ਹੈ…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਕਾਪੀ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਤਬਦੀਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਤਬਦੀਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਇਆ ਨਹੀਂ ਜਾ ਸਕਿਆ</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"ਵੇਰਵਿਆਂ ਨੂੰ ਵੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="close" msgid="3043722427445528732">"ਬੰਦ ਕਰੋ"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"ਇਹ ਫ਼ਾਈਲਾਂ ਕਾਪੀ ਨਹੀਂ ਹੋਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"ਇਹ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਨਹੀਂ ਹੋਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"ਇਹ ਫ਼ਾਈਲਾਂ ਕਿਸੇ ਹੋਰ ਫੌਰਮੈਟ ਵਿੱਚ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਬਣਾਈ ਗਈ।</item>
diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml
index 790c7b7..8a4d17c 100644
--- a/packages/DocumentsUI/res/values-pl/strings.xml
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ukryj elementy główne"</string>
     <string name="save_error" msgid="6167009778003223664">"Nie udało się zapisać dokumentu"</string>
     <string name="create_error" msgid="3735649141335444215">"Nie udało się utworzyć folderu"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Teraz nie można załadować zawartości"</string>
     <string name="root_recent" msgid="4470053704320518133">"Ostatnie"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> wolne"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Usługi pamięci masowej"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Więcej aplikacji"</string>
     <string name="empty" msgid="7858882803708117596">"Brak elementów"</string>
     <string name="no_results" msgid="6622510343880730446">"Brak wyników w %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Nie można otworzyć pliku"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
     <string name="share_via" msgid="8966594246261344259">"Udostępnij przez:"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopiowanie plików"</string>
@@ -92,15 +90,28 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Przygotowuję do kopiowania…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Przygotowuję przenoszenie…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Przygotowuję do usunięcia…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="few">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="many">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="other">Nie udało się skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+      <item quantity="one">Nie udało się skopiować <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="few">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="many">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="other">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+      <item quantity="one">Nie udało się przenieść <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="few">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="many">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+      <item quantity="other">Nie udało się usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+      <item quantity="one">Nie udało się usunąć <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Kliknij, by zobaczyć szczegóły"</string>
     <string name="close" msgid="3043722427445528732">"Zamknij"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Te pliki nie zostały przeniesione: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Te pliki zostały przekonwertowane na inny format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="few">Skopiowano <xliff:g id="COUNT_1">%1$d</xliff:g> pliki do schowka.</item>
diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
index 8e62483..391a053 100644
--- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
     <string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
     <string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo no momento"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
     <string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
     <string name="no_results" msgid="6622510343880730446">"Nenhum resultado em %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o arquivo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Preparando-se para excluir..."</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Tocar para ver detalhes"</string>
     <string name="close" msgid="3043722427445528732">"Fechar"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Esses arquivos foram convertidos em outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 02467fe..448ddfe 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
     <string name="save_error" msgid="6167009778003223664">"Falha ao guardar o documento"</string>
     <string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo neste momento"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> espaço livre"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Serv. de armazenamento"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Mais aplicações"</string>
     <string name="empty" msgid="7858882803708117596">"Sem itens"</string>
     <string name="no_results" msgid="6622510343880730446">"Sem correspondências para %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o ficheiro"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Partilhar através de"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"A copiar ficheiros"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"A preparar para copiar…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"A preparar para mover…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"A preparar para eliminar…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Não foi possível mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">Não foi possível eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+      <item quantity="one">Não foi possível eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Toque para ver detalhes"</string>
     <string name="close" msgid="3043722427445528732">"Fechar"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Os seguintes ficheiros não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Estes ficheiros foram convertidos para outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">Copiou <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros para a área de transferência.</item>
diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml
index 8e62483..391a053 100644
--- a/packages/DocumentsUI/res/values-pt/strings.xml
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
     <string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
     <string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Não é possível carregar o conteúdo no momento"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
     <string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
     <string name="no_results" msgid="6622510343880730446">"Nenhum resultado em %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Não é possível abrir o arquivo"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
     <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Preparando-se para excluir..."</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+      <item quantity="other">Não foi possível excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Tocar para ver detalhes"</string>
     <string name="close" msgid="3043722427445528732">"Fechar"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Esses arquivos foram convertidos em outro formato: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml
index a598fe46f..565a4e9 100644
--- a/packages/DocumentsUI/res/values-ro/strings.xml
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Ascundeți directoarele rădăcină"</string>
     <string name="save_error" msgid="6167009778003223664">"Salvarea documentului nu a reușit"</string>
     <string name="create_error" msgid="3735649141335444215">"Eroare la crearea dosarului"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Momentan, conținutul nu poate fi încărcat"</string>
     <string name="root_recent" msgid="4470053704320518133">"Recente"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> spațiu liber"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Servicii de stocare"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Alte aplicații"</string>
     <string name="empty" msgid="7858882803708117596">"Nu există elemente"</string>
     <string name="no_results" msgid="6622510343880730446">"Niciun rezultat în %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Fișierul nu poate fi deschis"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
     <string name="share_via" msgid="8966594246261344259">"Trimiteți prin"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Se copiază fișierele"</string>
@@ -89,15 +87,25 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Se pregătește copierea..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Se pregătește mutarea…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Se pregătește ștergerea…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="few">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+      <item quantity="other">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+      <item quantity="one">Nu s-a putut copia <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="few">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+      <item quantity="other">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+      <item quantity="one">Nu s-a putut muta <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="few">Nu s-au putut șterge <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+      <item quantity="other">Nu s-au putut șterge <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+      <item quantity="one">Nu s-a putut șterge <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Atingeți pentru a vedea detaliile"</string>
     <string name="close" msgid="3043722427445528732">"Închideți"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Aceste fișiere nu au fost mutate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Aceste fișiere au fost convertite în alt format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="few">Au fost copiate <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere în clipboard.</item>
diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml
index 934037e..ec97840 100644
--- a/packages/DocumentsUI/res/values-ru/strings.xml
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Скрыть"</string>
     <string name="save_error" msgid="6167009778003223664">"Не удалось сохранить документ"</string>
     <string name="create_error" msgid="3735649141335444215">"Не удалось создать папку"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Не удалось загрузить контент"</string>
     <string name="root_recent" msgid="4470053704320518133">"Недавние"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Свободно <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Службы хранения"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Другие приложения"</string>
     <string name="empty" msgid="7858882803708117596">"Ничего нет"</string>
     <string name="no_results" msgid="6622510343880730446">"В \"%1$s\" ничего не найдено"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Не удалось открыть файл"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
     <string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Копирование файлов"</string>
@@ -92,15 +90,28 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Подготовка…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Подготовка к удалению…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+      <item quantity="few">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+      <item quantity="many">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+      <item quantity="other">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+      <item quantity="few">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+      <item quantity="many">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+      <item quantity="other">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+      <item quantity="few">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+      <item quantity="many">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+      <item quantity="other">Не удалось удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Нажмите, чтобы узнать подробности."</string>
     <string name="close" msgid="3043722427445528732">"Закрыть"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Не удалось скопировать следующие файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Не удалось переместить следующие файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Формат этих файлов изменен: <xliff:g id="LIST">%1$s</xliff:g>."</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">Скопирован <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml
index f83a173..4d29021 100644
--- a/packages/DocumentsUI/res/values-sk/strings.xml
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Skryť korene"</string>
     <string name="save_error" msgid="6167009778003223664">"Dokument sa nepodarilo uložiť"</string>
     <string name="create_error" msgid="3735649141335444215">"Priečinok sa nepodarilo vytvoriť"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Obsah momentálne nie je možné načítať"</string>
     <string name="root_recent" msgid="4470053704320518133">"Nedávne"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Voľné <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Služby úložiska"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Ďalšie aplikácie"</string>
     <string name="empty" msgid="7858882803708117596">"Žiadne položky"</string>
     <string name="no_results" msgid="6622510343880730446">"Žiadne zhody – %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Súbor nie je možné otvoriť"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
     <string name="share_via" msgid="8966594246261344259">"Zdieľať"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kopírovanie súborov"</string>
@@ -92,15 +90,28 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Pripravuje sa na kopírovanie..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Prebieha príprava na presunutie…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Príprava na odstránenie…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="few">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súbory</item>
+      <item quantity="many">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
+      <item quantity="other">Nepodarilo sa skopírovať <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
+      <item quantity="one">Nepodarilo sa skopírovať <xliff:g id="COUNT_0">%1$d</xliff:g> súbor</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> súbory nie je možné presunúť</item>
+      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> súboru nie je možné presunúť</item>
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> súborov nie je možné presunúť</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> súbor nie je možné presunúť</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="few">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súbory</item>
+      <item quantity="many">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
+      <item quantity="other">Nepodarilo sa odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
+      <item quantity="one">Nepodarilo sa odstrániť <xliff:g id="COUNT_0">%1$d</xliff:g> súbor</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Klepnutím zobrazíte podrobnosti"</string>
     <string name="close" msgid="3043722427445528732">"Zavrieť"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Tieto súbory neboli presunuté: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Tieto súbory boli konvertované do iného formátu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="few">Do schránky boli skopírované <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml
index 0152b3a..e207c2e 100644
--- a/packages/DocumentsUI/res/values-sr/strings.xml
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Сакриј основне елементе"</string>
     <string name="save_error" msgid="6167009778003223664">"Чување документа није успело"</string>
     <string name="create_error" msgid="3735649141335444215">"Директоријум није направљен"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Учитавање садржаја тренутно није могуће"</string>
     <string name="root_recent" msgid="4470053704320518133">"Недавно"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"Слободно је <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Услуге складиштења"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Још апликација"</string>
     <string name="empty" msgid="7858882803708117596">"Нема ставки"</string>
     <string name="no_results" msgid="6622510343880730446">"Нема подударања у %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Отварање датотеке није успело"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
     <string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Копирање датотека"</string>
@@ -89,15 +87,25 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Припрема се премештање..."</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Припрема се брисање…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку</item>
+      <item quantity="few">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
+      <item quantity="other">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+      <item quantity="few">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+      <item quantity="other">Премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека није успело</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+      <item quantity="few">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке није успело</item>
+      <item quantity="other">Брисање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека није успело</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Додирните да бисте приказали детаље"</string>
     <string name="close" msgid="3043722427445528732">"Затвори"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Следеће датотеке нису премештене: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ове датотеке су конвертоване у други формат: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку у привремену меморију.</item>
diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
index 5aaf2b7..3f85a17 100644
--- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml
+++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"வழிகளை மறை"</string>
     <string name="save_error" msgid="6167009778003223664">"ஆவணத்தைச் சேமிப்பதில் தோல்வி"</string>
     <string name="create_error" msgid="3735649141335444215">"கோப்புறையை உருவாக்குவதில் தோல்வி"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"தற்போது உள்ளடக்கத்தை ஏற்ற முடியாது"</string>
     <string name="root_recent" msgid="4470053704320518133">"சமீபத்தியவை"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> இலவசம்"</string>
     <string name="root_type_service" msgid="2178854894416775409">"சேமிப்பிட சாதனங்கள்"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"மேலும் பயன்பாடுகள்"</string>
     <string name="empty" msgid="7858882803708117596">"எதுவும் இல்லை"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s இல் பொருந்தும் முடிவு இல்லை"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"கோப்பைத் திறக்க முடியாது"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
     <string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"கோப்புகளை நகலெடுத்தல்"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"நகர்த்துவதற்குத் தயார்படுத்துகிறது…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"நீக்கத் தயாராகிறது…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்க முடியவில்லை</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்க முடியவில்லை</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகர்த்த முடியவில்லை</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகர்த்த முடியவில்லை</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்க முடியவில்லை</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்க முடியவில்லை</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"விவரங்களைப் பார்க்க, தட்டவும்"</string>
     <string name="close" msgid="3043722427445528732">"மூடு"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"பின்வரும் கோப்புகள் நகலெடுக்கப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"பின்வரும் கோப்புகள் நகர்த்தப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"இந்தக் கோப்புகள் வேறொரு வடிவத்திற்கு மாற்றப்பட்டன: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">கிளிப்போர்டிற்கு <xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகள் நகலெடுக்கப்பட்டன.</item>
diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
index f247571..8562ef65 100644
--- a/packages/DocumentsUI/res/values-th/strings.xml
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"ซ่อนราก"</string>
     <string name="save_error" msgid="6167009778003223664">"การบันทึกเอกสารล้มเหลว"</string>
     <string name="create_error" msgid="3735649141335444215">"การสร้างโฟลเดอร์ล้มเหลว"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"โหลดเนื้อหาไม่ได้ในขณะนี้"</string>
     <string name="root_recent" msgid="4470053704320518133">"ล่าสุด"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"ว่าง <xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"บริการที่เก็บข้อมูล"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"แอปเพิ่มเติม"</string>
     <string name="empty" msgid="7858882803708117596">"ไม่มีรายการ"</string>
     <string name="no_results" msgid="6622510343880730446">"ไม่พบข้อมูลที่ตรงกันใน %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"เปิดไฟล์ไม่ได้"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
     <string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"กำลังคัดลอกไฟล์"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"กำลังเตรียมการย้าย…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"กำลังเตรียมลบ…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">คัดลอกไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+      <item quantity="one">คัดลอกไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">ย้ายไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+      <item quantity="one">ย้ายไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">ลบไม่ได้ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+      <item quantity="one">ลบไม่ได้ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"แตะเพื่อดูรายละเอียด"</string>
     <string name="close" msgid="3043722427445528732">"ปิด"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"ไม่ได้คัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"ไม่ได้ย้ายไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"ไฟล์ต่อไปนี้แปลงเป็นอีกรูปแบบหนึ่งแล้ว: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">คัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์ไปยังคลิปบอร์ดแล้ว</item>
diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
index bca1f84..de0c9bd 100644
--- a/packages/DocumentsUI/res/values-tl/strings.xml
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Itago ang mga root"</string>
     <string name="save_error" msgid="6167009778003223664">"Hindi na-save ang dokumento"</string>
     <string name="create_error" msgid="3735649141335444215">"Hindi nagawa ang folder"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Hindi ma-load ang content sa ngayon"</string>
     <string name="root_recent" msgid="4470053704320518133">"Kamakailan"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ang libre"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Mga serbisyo ng storage"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Higit pang apps"</string>
     <string name="empty" msgid="7858882803708117596">"Walang mga item"</string>
     <string name="no_results" msgid="6622510343880730446">"Walang mga katugma sa %1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Hindi mabuksan ang file"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
     <string name="share_via" msgid="8966594246261344259">"Ibahagi sa pamamagitan ng"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Kinokopya ang mga file"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Naghahanda para sa paglilipat…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Naghahanda para sa pag-delete…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="other">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Hindi mailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="other">Hindi mailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Hindi ma-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+      <item quantity="other">Hindi ma-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"I-tap upang tingnan ang mga detalye"</string>
     <string name="close" msgid="3043722427445528732">"Isara"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Hindi nakopya ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Hindi nailipat ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Na-convert ang mga file na ito sa ibang format: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">Nakopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file sa clipboard.</item>
diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml
index 7ee0218..c9245c6 100644
--- a/packages/DocumentsUI/res/values-tr/strings.xml
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Kökleri sakla"</string>
     <string name="save_error" msgid="6167009778003223664">"Doküman kaydedilemedi"</string>
     <string name="create_error" msgid="3735649141335444215">"Klasör oluşturulamadı"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"İçerik şu anda yüklenemiyor"</string>
     <string name="root_recent" msgid="4470053704320518133">"En son"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> boş"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Depolama hizmetleri"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Diğer uygulamalar"</string>
     <string name="empty" msgid="7858882803708117596">"Öğe yok"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s içinde eşleşme bulunamadı"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Dosya açılamıyor"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
     <string name="share_via" msgid="8966594246261344259">"Şunu kullanarak paylaş:"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Dosyalar kopyalanıyor"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmak için hazırlanıyor…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"Taşıma için hazırlanıyor…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Silmek için hazırlanıyor…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanamadı</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanamadı</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya taşınamadı</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya taşınamadı</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya silinemedi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya silinemedi</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Ayrıntıları görmek için hafifçe dokunun"</string>
     <string name="close" msgid="3043722427445528732">"Kapat"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Şu dosyalar kopyalanamadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Şu dosyalar taşınamadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Bu dosyalar başka bir biçime dönüştürüldü: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya panoya kopyalandı.</item>
diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
index 1ef2926..40831eb 100644
--- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml
+++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"روٹس کو چھپائیں"</string>
     <string name="save_error" msgid="6167009778003223664">"دستاویز کو محفوظ کرنے میں ناکام ہو گیا۔"</string>
     <string name="create_error" msgid="3735649141335444215">"فولڈر بنانے میں ناکام ہو گیا"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"اس وقت مواد لوڈ نہیں ہو سکتا"</string>
     <string name="root_recent" msgid="4470053704320518133">"حالیہ"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> خالی"</string>
     <string name="root_type_service" msgid="2178854894416775409">"اسٹوریج سروسز"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"مزید ایپس"</string>
     <string name="empty" msgid="7858882803708117596">"کوئی آئٹمز نہيں ہیں"</string>
     <string name="no_results" msgid="6622510343880730446">"‏%1$s میں کوئی مماثل نہیں"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"فائل نہیں کھل سکتی"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
     <string name="share_via" msgid="8966594246261344259">"اشتراک کریں بذریعہ"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"فائلیں کاپی ہو رہی ہیں"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"حذف کرنے کیلئے تیاری ہو رہی ہے…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں کاپی نہیں ہو سکیں</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی نہیں ہو سکی</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں منتقل نہیں ہو سکیں</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل منتقل نہیں ہو سکی</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف نہیں ہو سکیں</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف نہیں ہو سکی</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"تفصیلات دیکھنے کیلئے تھپتھپائیں"</string>
     <string name="close" msgid="3043722427445528732">"بند کریں"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"یہ فائلیں کاپی نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"یہ فائلیں منتقل نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"ان فائلوں کو ایک دوسرے فارمیٹ میں تبدیل کیا گیا تھا: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز کلپ بورڈ پر کاپی کی گئیں۔</item>
diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
index b811125..48fa9a6 100644
--- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
+++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml
@@ -31,7 +31,7 @@
     <string name="menu_save" msgid="2394743337684426338">"Saqlash"</string>
     <string name="menu_share" msgid="3075149983979628146">"Ulashish"</string>
     <string name="menu_delete" msgid="8138799623850614177">"O‘chirish"</string>
-    <string name="menu_select_all" msgid="8323579667348729928">"Barchasini belgilash"</string>
+    <string name="menu_select_all" msgid="8323579667348729928">"Hammasini belgilash"</string>
     <string name="menu_copy" msgid="3612326052677229148">"Nusxalash…"</string>
     <string name="menu_move" msgid="1828090633118079817">"Ko‘chirib o‘tkazish…"</string>
     <string name="menu_new_window" msgid="1226032889278727538">"Yangi oyna"</string>
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Asosiy jildlarni yashirish"</string>
     <string name="save_error" msgid="6167009778003223664">"Hujjat saqlanmadi"</string>
     <string name="create_error" msgid="3735649141335444215">"Jild yaratilmadi"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Ayni paytda kontentni yuklab bo‘lmayapti"</string>
     <string name="root_recent" msgid="4470053704320518133">"Yaqinda"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bo‘sh"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Xotira xizmatlari"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Ko‘proq dasturlar"</string>
     <string name="empty" msgid="7858882803708117596">"Hech narsa yo‘q"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s jildidan topilmadi"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Fayl ochilmadi"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ba’zi hujjatlar o‘chirilmadi"</string>
     <string name="share_via" msgid="8966594246261344259">"Quyidagi orqali ulashish"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Fayllar nusxalanmoqda"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ko‘chirishga tayyorgarlik…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"O‘chirishga tayyorlanmoqda…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olib bo‘lmadi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olib bo‘lmadi</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta faylni ko‘chirib bo‘lmadi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta faylni ko‘chirib bo‘lmadi</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta faylni o‘chirib bo‘lmadi</item>
+      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta faylni o‘chirib bo‘lmadi</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Batafsil ma’lumot olish uchun bosing"</string>
     <string name="close" msgid="3043722427445528732">"Yopish"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Quyidagi fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Quyidagi fayllar ko‘chirilmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Ushbu fayllar boshqa formatga o‘girildi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan vaqtinchalik xotiraga nusxa olindi.</item>
diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
index 0ad4e3b..bb48b0c 100644
--- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"隐藏根目录"</string>
     <string name="save_error" msgid="6167009778003223664">"无法保存文档"</string>
     <string name="create_error" msgid="3735649141335444215">"无法创建文件夹"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"暂时无法加载内容"</string>
     <string name="root_recent" msgid="4470053704320518133">"最近"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"可用空间:<xliff:g id="SIZE">%1$s</xliff:g>"</string>
     <string name="root_type_service" msgid="2178854894416775409">"存储服务"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"更多应用"</string>
     <string name="empty" msgid="7858882803708117596">"无任何文件"</string>
     <string name="no_results" msgid="6622510343880730446">"%1$s中没有任何相符项"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"无法打开文件"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
     <string name="share_via" msgid="8966594246261344259">"分享方式"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"正在复制文件"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
     <string name="move_preparing" msgid="2772219441375531410">"正在准备移动…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"正在准备删除…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="other">无法复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
+      <item quantity="one">无法复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="other">无法移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
+      <item quantity="one">无法移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="other">无法删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
+      <item quantity="one">无法删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"点按即可查看详情"</string>
     <string name="close" msgid="3043722427445528732">"关闭"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"无法复制以下文件:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"无法移动以下文件:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"下列文件已转换成其他格式:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">已将 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件复制到剪贴板。</item>
diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
index 44ac652..f8d46d5 100644
--- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -98,8 +98,8 @@
     </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"輕按即可查看詳細資訊"</string>
     <string name="close" msgid="3043722427445528732">"關閉"</string>
-    <string name="copy_failure_alert_content" msgid="4563147454522476183">"未複製下列檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
-    <string name="move_failure_alert_content" msgid="2635075788682922861">"未移動下列檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"以下檔案未能移動:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"這些檔案已轉換成其他格式:<xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="other">已複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案到剪貼簿。</item>
diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
index f450209..c49500c 100644
--- a/packages/DocumentsUI/res/values-zu/strings.xml
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -53,8 +53,7 @@
     <string name="drawer_close" msgid="7602734368552123318">"Fihla izimpande"</string>
     <string name="save_error" msgid="6167009778003223664">"Yehlulekile ukulondoloza idokhumenti"</string>
     <string name="create_error" msgid="3735649141335444215">"Yehlulekile ukudala ifolda"</string>
-    <!-- no translation found for query_error (5999895349602476581) -->
-    <skip />
+    <string name="query_error" msgid="5999895349602476581">"Ayikwazanga ukulayisha okuqukethwe okwamanje"</string>
     <string name="root_recent" msgid="4470053704320518133">"Okwakamuva"</string>
     <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> okhululekile"</string>
     <string name="root_type_service" msgid="2178854894416775409">"Amasevisi wesitoreji"</string>
@@ -63,8 +62,7 @@
     <string name="root_type_apps" msgid="8838065367985945189">"Izinhlelo zokusebenza eziningi"</string>
     <string name="empty" msgid="7858882803708117596">"Azikho izinto"</string>
     <string name="no_results" msgid="6622510343880730446">"Akukho okufanayo ku-%1$s"</string>
-    <!-- no translation found for toast_no_application (4632640357724698144) -->
-    <skip />
+    <string name="toast_no_application" msgid="4632640357724698144">"Ayikwazanga ukuvula ifayela"</string>
     <string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
     <string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
     <string name="copy_notification_title" msgid="6374299806748219777">"Ikopisha amafayela"</string>
@@ -86,15 +84,22 @@
     <string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
     <string name="move_preparing" msgid="2772219441375531410">"Ilungiselela ukuhambisa…"</string>
     <string name="delete_preparing" msgid="5655813182533491992">"Ilungiselela ukususa…"</string>
-    <!-- no translation found for copy_error_notification_title (7160447124922897689) -->
-    <!-- no translation found for move_error_notification_title (2710901971014783012) -->
-    <!-- no translation found for delete_error_notification_title (7228393157786591199) -->
+    <plurals name="copy_error_notification_title" formatted="false" msgid="7160447124922897689">
+      <item quantity="one">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <plurals name="move_error_notification_title" formatted="false" msgid="2710901971014783012">
+      <item quantity="one">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
+    <plurals name="delete_error_notification_title" formatted="false" msgid="7228393157786591199">
+      <item quantity="one">Ayikwazanga ukususa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+      <item quantity="other">Ayikwazanga ukususa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+    </plurals>
     <string name="notification_touch_for_details" msgid="6268189413228855582">"Thepha ukuze ubuke imininingwane"</string>
     <string name="close" msgid="3043722427445528732">"Vala"</string>
-    <!-- no translation found for copy_failure_alert_content (4563147454522476183) -->
-    <skip />
-    <!-- no translation found for move_failure_alert_content (2635075788682922861) -->
-    <skip />
+    <string name="copy_failure_alert_content" msgid="4563147454522476183">"Lawo mafayela awakopishwanga: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+    <string name="move_failure_alert_content" msgid="2635075788682922861">"Lawa mafayela awazange ahanjiswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <string name="copy_converted_warning_content" msgid="5753861488218674361">"Lawo mafayela aguqulelwe kwenye ifomethi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
     <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
       <item quantity="one">Kukopishwe amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g> kubhodi lokunamathisela.</item>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 3c21a21..648c79e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -23,7 +23,6 @@
 import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
 import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_SIDE;
 import static com.android.internal.util.Preconditions.checkArgument;
-import static com.android.internal.util.Preconditions.checkState;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -42,6 +41,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.Spinner;
@@ -49,6 +49,7 @@
 import com.android.documentsui.SearchManager.SearchManagerListener;
 import com.android.documentsui.State.ViewMode;
 import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.Model;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.RootInfo;
@@ -83,7 +84,9 @@
     // We use the time gap to figure out whether to close app or reopen the drawer.
     private long mDrawerLastFiddled;
 
-    public abstract void onDocumentPicked(DocumentInfo doc, @Nullable SiblingProvider siblings);
+    private boolean mNavDrawerHasFocus;
+
+    public abstract void onDocumentPicked(DocumentInfo doc, Model model);
     public abstract void onDocumentsPicked(List<DocumentInfo> docs);
 
     abstract void onTaskFinished(Uri... uris);
@@ -216,11 +219,13 @@
         return state;
     }
 
-    void onStackRestored(boolean restored, boolean external) {}
+    public void setRootsDrawerOpen(boolean open) {
+        mNavigator.revealRootsDrawer(open);
+    }
 
     void onRootPicked(RootInfo root) {
-        // Skip refreshing if root didn't change
-        if(root.equals(getCurrentRoot())) {
+        // Skip refreshing if root nor directory didn't change
+        if (root.equals(getCurrentRoot()) && mState.stack.size() == 1) {
             return;
         }
 
@@ -458,8 +463,7 @@
      * Set mode based on explicit user action.
      */
     void setViewMode(@ViewMode int mode) {
-        checkState(mState.stack.root != null);
-        LocalPreferences.setViewMode(this, mState.stack.root, mode);
+        LocalPreferences.setViewMode(this, getCurrentRoot(), mode);
         mState.derivedMode = mode;
 
         // view icon needs to be updated, but we *could* do it
@@ -539,7 +543,8 @@
         // Do some "do what a I want" drawer fiddling, but don't
         // do it if user already hit back recently and we recently
         // did some fiddling.
-        if ((System.currentTimeMillis() - mDrawerLastFiddled) > DRAWER_NO_FIDDLE_DELAY) {
+        if (mDrawer.isPresent()
+                && (System.currentTimeMillis() - mDrawerLastFiddled) > DRAWER_NO_FIDDLE_DELAY) {
             // Close drawer if it is open.
             if (mDrawer.isOpen()) {
                 mDrawer.setOpen(false);
@@ -577,6 +582,54 @@
         }
     }
 
+    /**
+     * Declare a global key handler to route key events when there isn't a specific focus view. This
+     * covers the scenario where a user opens DocumentsUI and just starts typing.
+     *
+     * @param keyCode
+     * @param event
+     * @return
+     */
+    @CallSuper
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (Events.isNavigationKeyCode(keyCode)) {
+            // Forward all unclaimed navigation keystrokes to the DirectoryFragment. This causes any
+            // stray navigation keystrokes focus the content pane, which is probably what the user
+            // is trying to do.
+            DirectoryFragment df = DirectoryFragment.get(getFragmentManager());
+            if (df != null) {
+                df.requestFocus();
+                return true;
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+            toggleNavDrawerFocus();
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+    /**
+     * Toggles focus between the navigation drawer and the directory listing. If the drawer isn't
+     * locked, open/close it as appropriate.
+     */
+    void toggleNavDrawerFocus() {
+        if (mNavDrawerHasFocus) {
+            mDrawer.setOpen(false);
+            DirectoryFragment df = DirectoryFragment.get(getFragmentManager());
+            if (df != null) {
+                df.requestFocus();
+            }
+        } else {
+            mDrawer.setOpen(true);
+            RootsFragment rf = RootsFragment.get(getFragmentManager());
+            if (rf != null) {
+                rf.requestFocus();
+            }
+        }
+        mNavDrawerHasFocus = !mNavDrawerHasFocus;
+    }
+
     DocumentInfo getRootDocumentBlocking(RootInfo root) {
         try {
             final Uri uri = DocumentsContract.buildDocumentUri(
@@ -647,17 +700,4 @@
             }
         }
     }
-
-    /**
-     * Interface providing access to current view of documents
-     * even when all documents are not homed to the same parent.
-     */
-    public interface SiblingProvider {
-        /**
-         * Returns the cursor for the selected document. The cursor can be used to retrieve
-         * details about a document and its siblings.
-         * @return
-         */
-        Cursor getCursor();
-    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index df036b9..40bd754 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -36,6 +36,7 @@
 import android.support.design.widget.Snackbar;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.EditText;
@@ -86,9 +87,9 @@
                     @Override
                     public boolean onEditorAction(
                             TextView view, int actionId, @Nullable KeyEvent event) {
-                        if (event != null
+                        if ((actionId == EditorInfo.IME_ACTION_DONE) || (event != null
                                 && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
-                                && event.hasNoModifiers()) {
+                                && event.hasNoModifiers())) {
                             createDirectory(editText.getText().toString());
                             dialog.dismiss();
                             return true;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 3485fe4..29bb5e4 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -32,7 +32,6 @@
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
@@ -49,6 +48,7 @@
 import com.android.documentsui.RecentsProvider.RecentColumns;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
 import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.Model;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
@@ -134,15 +134,18 @@
         }
 
         if (state.action == ACTION_PICK_COPY_DESTINATION) {
+            // Indicates that a copy operation (or move) includes a directory.
+            // Why? Directory creation isn't supported by some roots (like Downloads).
+            // This allows us to restrict available roots to just those with support.
             state.directoryCopy = intent.getBooleanExtra(
                     Shared.EXTRA_DIRECTORY_COPY, false);
-            state.transferMode = intent.getIntExtra(FileOperationService.EXTRA_OPERATION,
+            state.copyOperationSubType = intent.getIntExtra(
+                    FileOperationService.EXTRA_OPERATION,
                     FileOperationService.OPERATION_COPY);
         }
     }
 
-    @Override
-    void onStackRestored(boolean restored, boolean external) {
+    private void onStackRestored(boolean restored, boolean external) {
         // Show drawer when no stack restored, but only when requesting
         // non-visual content. However, if we last used an external app,
         // drawer is always shown.
@@ -157,6 +160,9 @@
         if (external && mState.action == ACTION_GET_CONTENT) {
             showDrawer = true;
         }
+        if (mState.action == ACTION_PICK_COPY_DESTINATION) {
+            showDrawer = true;
+        }
 
         if (showDrawer) {
             mNavigator.revealRootsDrawer(true);
@@ -308,7 +314,7 @@
             mState.action == ACTION_PICK_COPY_DESTINATION) {
             final PickFragment pick = PickFragment.get(fm);
             if (pick != null) {
-                pick.setPickTarget(mState.action, mState.transferMode, cwd);
+                pick.setPickTarget(mState.action, mState.copyOperationSubType, cwd);
             }
         }
     }
@@ -329,12 +335,8 @@
         mNavigator.revealRootsDrawer(false);
     }
 
-    public void setRootsDrawerOpen(boolean open) {
-        mNavigator.revealRootsDrawer(open);
-    }
-
     @Override
-    public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) {
+    public void onDocumentPicked(DocumentInfo doc, Model model) {
         final FragmentManager fm = getFragmentManager();
         if (doc.isContainer()) {
             openContainerDocument(doc);
@@ -425,7 +427,7 @@
             // Picking a copy destination is only used internally by us, so we
             // don't need to extend permissions to the caller.
             intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
-            intent.putExtra(FileOperationService.EXTRA_OPERATION, mState.transferMode);
+            intent.putExtra(FileOperationService.EXTRA_OPERATION, mState.copyOperationSubType);
         } else {
             intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
index d589d5e..f7a45e2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java
@@ -36,6 +36,7 @@
 import android.widget.Toolbar;
 
 import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.Model;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.util.Preconditions;
@@ -132,7 +133,7 @@
     }
 
     @Override
-    public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) {
+    public void onDocumentPicked(DocumentInfo doc, Model model) {
         Preconditions.checkArgument(!doc.isDirectory());
         // First try managing the document; we expect manager to filter
         // based on authority, so we don't grant.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Events.java b/packages/DocumentsUI/src/com/android/documentsui/Events.java
index 99b425e..14d4e2d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Events.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Events.java
@@ -91,6 +91,8 @@
             case KeyEvent.KEYCODE_DPAD_RIGHT:
             case KeyEvent.KEYCODE_MOVE_HOME:
             case KeyEvent.KEYCODE_MOVE_END:
+            case KeyEvent.KEYCODE_PAGE_UP:
+            case KeyEvent.KEYCODE_PAGE_DOWN:
                 return true;
             default:
                 return false;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index c81f342..c0faba3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -43,6 +43,7 @@
 import com.android.documentsui.OperationDialogFragment.DialogType;
 import com.android.documentsui.RecentsProvider.ResumeColumns;
 import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.dirlist.Model;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
@@ -272,24 +273,20 @@
     }
 
     @Override
-    public void onDocumentPicked(DocumentInfo doc, @Nullable SiblingProvider siblings) {
+    public void onDocumentPicked(DocumentInfo doc, Model model) {
         if (doc.isContainer()) {
             openContainerDocument(doc);
         } else {
-            openDocument(doc, siblings);
+            openDocument(doc, model);
         }
     }
 
     /**
      * Launches an intent to view the specified document.
      */
-    private void openDocument(DocumentInfo doc, @Nullable SiblingProvider siblings) {
-        Intent intent = null;
-        if (siblings != null) {
-            QuickViewIntentBuilder builder = new QuickViewIntentBuilder(
-                    getPackageManager(), getResources(), doc, siblings);
-            intent = builder.build();
-        }
+    private void openDocument(DocumentInfo doc, Model model) {
+        Intent intent = new QuickViewIntentBuilder(
+                getPackageManager(), getResources(), doc, model).build();
 
         if (intent != null) {
             // TODO: un-work around issue b/24963914. Should be fixed soon.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
index ff1940a..4cba135 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java
@@ -132,7 +132,7 @@
             showBreadcrumb(true);
             mToolbar.setTitle(null);
             mIgnoreNextNavigation = true;
-            mBreadcrumb.setSelection(mBreadcrumbAdapter.getCount() - 1);
+            mBreadcrumb.setSelection(mBreadcrumbAdapter.getCount() - 1, false);
         }
 
         if (DEBUG) Log.d(TAG, "Final toolbar title is: " + mToolbar.getTitle());
diff --git a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
index d601550..025faea 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
@@ -17,6 +17,8 @@
 package com.android.documentsui;
 
 import static android.os.Environment.isStandardDirectory;
+import static android.os.storage.StorageVolume.EXTRA_DIRECTORY_NAME;
+import static android.os.storage.StorageVolume.EXTRA_STORAGE_VOLUME;
 import static com.android.documentsui.Shared.DEBUG;
 
 import android.app.Activity;
@@ -35,9 +37,11 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
 import android.os.storage.VolumeInfo;
 import android.provider.DocumentsContract;
 import android.text.TextUtils;
@@ -63,16 +67,31 @@
         super.onCreate(savedInstanceState);
 
         final Intent intent = getIntent();
-        if (intent == null || intent.getData() == null) {
-            Log.d(TAG, "missing intent or intent data: " + intent);
+        if (intent == null) {
+            if (DEBUG) Log.d(TAG, "missing intent");
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
+        final Parcelable storageVolume = intent.getParcelableExtra(EXTRA_STORAGE_VOLUME);
+        if (!(storageVolume instanceof StorageVolume)) {
+            if (DEBUG)
+                Log.d(TAG, "extra " + EXTRA_STORAGE_VOLUME + " is not a StorageVolume: "
+                        + storageVolume);
+            setResult(RESULT_CANCELED);
+            finish();
+            return;
+        }
+        final String directoryName = intent.getStringExtra(EXTRA_DIRECTORY_NAME);
+        if (directoryName == null) {
+            if (DEBUG) Log.d(TAG, "missing extra " + EXTRA_DIRECTORY_NAME + " on " + intent);
             setResult(RESULT_CANCELED);
             finish();
             return;
         }
 
-        final String path = intent.getData().getPath();
         final int userId = UserHandle.myUserId();
-        if (!showFragment(this, userId, path)) {
+        if (!showFragment(this, userId, (StorageVolume) storageVolume, directoryName)) {
             setResult(RESULT_CANCELED);
             finish();
             return;
@@ -80,20 +99,20 @@
     }
 
     /**
-     * Validates the given {@code path} and display the appropriate dialog asking the user to grant
-     * access to it.
+     * Validates the given path (volume + directory) and display the appropriate dialog asking the
+     * user to grant access to it.
      */
-    static boolean showFragment(Activity activity, int userId, String path) {
-        Log.d(TAG, "showFragment() for path " + path + " and user " + userId);
-        if (path == null) {
-            Log.e(TAG, "INTERNAL ERROR: showFragment() with null path");
-            return false;
-        }
+    private static boolean showFragment(Activity activity, int userId, StorageVolume storageVolume,
+            String directoryName) {
+        if (DEBUG)
+            Log.d(TAG, "showFragment() for volume " + storageVolume.dump() + ", directory "
+                    + directoryName + ", and user " + userId);
         File file;
         try {
-            file = new File(new File(path).getCanonicalPath());
+            file = new File(storageVolume.getPathFile(), directoryName).getCanonicalFile();
         } catch (IOException e) {
-            Log.e(TAG, "Could not get canonical file from " + path);
+            Log.e(TAG, "Could not get canonical file for volume " + storageVolume.dump()
+                    + " and directory " + directoryName);
             return false;
         }
         final StorageManager sm =
@@ -104,7 +123,9 @@
 
         // Verify directory is valid.
         if (TextUtils.isEmpty(directory) || !isStandardDirectory(directory)) {
-            Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '" + path + "')");
+            if (DEBUG)
+                Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '"
+                        + file.getAbsolutePath() + "')");
             return false;
         }
 
@@ -123,7 +144,7 @@
             }
         }
         if (volumeLabel == null) {
-            Log.e(TAG, "Could not get volume for " + path);
+            Log.e(TAG, "Could not get volume for " + file);
             return false;
         }
 
@@ -165,13 +186,13 @@
         final File userPath = volume.getPathForUser(userId);
         final String path = userPath == null ? null : volume.getPathForUser(userId).getPath();
         final boolean isVisible = volume.isVisibleForWrite(userId);
-        if (DEBUG) {
+        if (DEBUG)
             Log.d(TAG, "Volume: " + volume + " userId: " + userId + " root: " + root
                     + " volumePath: " + volume.getPath().getPath()
                     + " pathForUser: " + path
                     + " internalPathForUser: " + volume.getInternalPath()
                     + " isVisible: " + isVisible);
-        }
+
         return volume.isVisibleForWrite(userId) && root.equals(path);
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
index bbf4682..287c904 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/PickFragment.java
@@ -16,6 +16,10 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.services.FileOperationService.OPERATION_COPY;
+import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
+import static com.android.internal.util.Preconditions.checkArgument;
+
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -27,6 +31,7 @@
 import android.widget.Button;
 
 import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.services.FileOperationService.OpType;
 
 /**
  * Display pick confirmation bar, usually for selecting a directory.
@@ -35,7 +40,7 @@
     public static final String TAG = "PickFragment";
 
     private int mAction;
-    private int mTransferMode;
+    private @OpType int mOperationType;
     private DocumentInfo mPickTarget;
     private View mContainer;
     private Button mPick;
@@ -92,9 +97,10 @@
     /**
      * @param action Which action defined in State is the picker shown for.
      */
-    public void setPickTarget(int action, int transferMode, DocumentInfo pickTarget) {
+    public void setPickTarget(int action, @OpType int operationType, DocumentInfo pickTarget) {
+        checkArgument(operationType == OPERATION_COPY || operationType == OPERATION_MOVE);
         mAction = action;
-        mTransferMode = transferMode;
+        mOperationType = operationType;
         mPickTarget = pickTarget;
         if (mContainer != null) {
             updateView();
@@ -111,7 +117,8 @@
                 mCancel.setVisibility(View.GONE);
                 break;
             case State.ACTION_PICK_COPY_DESTINATION:
-                mPick.setText(R.string.button_copy);
+                mPick.setText(mOperationType == OPERATION_MOVE
+                        ? R.string.button_move : R.string.button_copy);
                 mCancel.setVisibility(View.VISIBLE);
                 break;
             default:
diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
index 4543162..a77a9b3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -33,34 +33,36 @@
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Range;
 
-import com.android.documentsui.BaseActivity.SiblingProvider;
+import com.android.documentsui.dirlist.Model;
 import com.android.documentsui.model.DocumentInfo;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Provides support for gather a list of quick-viewable files into a quick view intent.
  */
 final class QuickViewIntentBuilder {
+    private static final int MAX_CLIP_ITEMS = 1000;
 
     private final DocumentInfo mDocument;
-    private final SiblingProvider mSiblings;
+    private final Model mModel;
 
     private final PackageManager mPkgManager;
     private final Resources mResources;
 
-    private ClipData mClipData;
-    private int mDocumentLocation;
-
     public QuickViewIntentBuilder(
             PackageManager pkgManager,
             Resources resources,
             DocumentInfo doc,
-            SiblingProvider siblings) {
+            Model model) {
 
         mPkgManager = pkgManager;
         mResources = resources;
         mDocument = doc;
-        mSiblings = siblings;
+        mModel = model;
     }
 
     /**
@@ -78,12 +80,28 @@
             intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             intent.setPackage(trustedPkg);
             if (hasRegisteredHandler(intent)) {
-                Cursor cursor = mSiblings.getCursor();
-                for (int i = 0; i < cursor.getCount(); i++) {
-                    onNextItem(i, cursor);
+                final ArrayList<Uri> uris = new ArrayList<Uri>();
+                final int documentLocation = collectViewableUris(uris);
+                final Range<Integer> range = computeSiblingsRange(uris, documentLocation);
+
+                ClipData clipData = null;
+                ClipData.Item item;
+                Uri uri;
+                for (int i = range.getLower(); i <= range.getUpper(); i++) {
+                    uri = uris.get(i);
+                    item = new ClipData.Item(uri);
+                    if (DEBUG) Log.d(TAG, "Including file: " + uri);
+                    if (clipData == null) {
+                        clipData = new ClipData(
+                                "URIs", new String[] { ClipDescription.MIMETYPE_TEXT_URILIST },
+                                item);
+                    } else {
+                        clipData.addItem(item);
+                    }
                 }
-                intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
-                intent.setClipData(mClipData);
+
+                intent.putExtra(Intent.EXTRA_INDEX, documentLocation);
+                intent.setClipData(clipData);
 
                 return intent;
             } else {
@@ -94,35 +112,63 @@
         return null;
     }
 
+    private int collectViewableUris(ArrayList<Uri> uris) {
+        final List<String> siblingIds = mModel.getModelIds();
+        uris.ensureCapacity(siblingIds.size());
+
+        int documentLocation = 0;
+        Cursor cursor;
+        String mimeType;
+        String id;
+        String authority;
+        Uri uri;
+
+        // Cursor's are not guaranteed to be immutable. Hence, traverse it only once.
+        for (int i = 0; i < siblingIds.size(); i++) {
+            cursor = mModel.getItem(siblingIds.get(i));
+
+            mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+                continue;
+            }
+
+            id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+            authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+            uri = DocumentsContract.buildDocumentUri(authority, id);
+
+            if (id.equals(mDocument.documentId)) {
+                if (DEBUG) Log.d(TAG, "Found starting point for QV. " + i);
+                documentLocation = i;
+            }
+
+            uris.add(uri);
+        }
+
+        return documentLocation;
+    }
+
+    private static Range<Integer> computeSiblingsRange(List<Uri> uris, int documentLocation) {
+        // Restrict number of siblings to avoid hitting the IPC limit.
+        // TODO: Remove this restriction once ClipData can hold an arbitrary number of
+        // items.
+        int firstSibling;
+        int lastSibling;
+        if (documentLocation < uris.size() / 2) {
+            firstSibling = Math.max(0, documentLocation - MAX_CLIP_ITEMS / 2);
+            lastSibling = Math.min(uris.size() - 1, firstSibling + MAX_CLIP_ITEMS - 1);
+        } else {
+            lastSibling = Math.min(uris.size() - 1, documentLocation + MAX_CLIP_ITEMS / 2);
+            firstSibling = Math.max(0, lastSibling - MAX_CLIP_ITEMS + 1);
+        }
+
+        if (DEBUG) Log.d(TAG, "Copmuted siblings from index: " + firstSibling
+                + " to: " + lastSibling);
+
+        return new Range(firstSibling, lastSibling);
+    }
+
     private boolean hasRegisteredHandler(Intent intent) {
         // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
         return intent.resolveActivity(mPkgManager) != null;
     }
-
-    private void onNextItem(int index, Cursor cursor) {
-        cursor.moveToPosition(index);
-
-        String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
-        if (Document.MIME_TYPE_DIR.equals(mimeType)) {
-            return;
-        }
-
-        String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
-        String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
-        Uri uri = DocumentsContract.buildDocumentUri(authority, id);
-        if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);
-
-        if (id.equals(mDocument.documentId)) {
-            if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
-            mDocumentLocation = index;
-        }
-
-        ClipData.Item item = new ClipData.Item(uri);
-        if (mClipData == null) {
-            mClipData = new ClipData(
-                    "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
-        } else {
-            mClipData.addItem(item);
-        }
-    }
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index 7dac0c1..0e27622 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -83,7 +83,7 @@
 
         final View view = inflater.inflate(R.layout.fragment_directory, container, false);
 
-        mRecView = (RecyclerView) view.findViewById(R.id.list);
+        mRecView = (RecyclerView) view.findViewById(R.id.dir_list);
         mRecView.setLayoutManager(new LinearLayoutManager(getContext()));
         mRecView.addOnItemTouchListener(mItemListener);
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index 26bda31..53f8297 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -89,7 +89,7 @@
         final Context context = inflater.getContext();
 
         final View view = inflater.inflate(R.layout.fragment_roots, container, false);
-        mList = (ListView) view.findViewById(android.R.id.list);
+        mList = (ListView) view.findViewById(R.id.roots_list);
         mList.setOnItemClickListener(mItemListener);
         mList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
         return view;
@@ -167,6 +167,13 @@
         }
     }
 
+    /**
+     * Attempts to shift focus back to the navigation drawer.
+     */
+    public void requestFocus() {
+        mList.requestFocus();
+    }
+
     private void showAppDetails(ResolveInfo ri) {
         final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
         intent.setData(Uri.fromParts("package", ri.activityInfo.packageName, null));
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsList.java b/packages/DocumentsUI/src/com/android/documentsui/RootsList.java
new file mode 100644
index 0000000..bf03ffd
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsList.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.ListView;
+
+/**
+ * The list in the navigation drawer. This class exists for the purpose of overriding the key
+ * handler on ListView. Ignoring keystrokes (e.g. the tab key) cannot be properly done using
+ * View.OnKeyListener.
+ */
+public class RootsList extends ListView {
+
+    // Multiple constructors are needed to handle all the different ways this View could be
+    // constructed by the framework. Don't remove them!
+    public RootsList(Context context) {
+        super(context);
+    }
+
+    public RootsList(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public RootsList(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public RootsList(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            // Ignore tab key events - this causes them to bubble up to the global key handler where
+            // they are appropriately handled. See BaseActivity.onKeyDown.
+            case KeyEvent.KEYCODE_TAB:
+                return false;
+            // Prevent left/right arrow keystrokes from shifting focus away from the roots list.
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+                return true;
+            default:
+                return super.onKeyDown(keyCode, event);
+        }
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index d141de6..81a0635 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -16,16 +16,21 @@
 
 package com.android.documentsui;
 
+import static com.android.documentsui.Shared.DEBUG;
+
 import android.annotation.IntDef;
 import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
+import com.android.documentsui.services.FileOperationService.OpType;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -35,6 +40,8 @@
 
 public class State implements android.os.Parcelable {
 
+    private static final String TAG = "State";
+
     public static final int ACTION_OPEN = 1;
     public static final int ACTION_CREATE = 2;
     public static final int ACTION_GET_CONTENT = 3;
@@ -77,14 +84,24 @@
     public boolean forceAdvanced;
     public boolean showAdvanced;
     public boolean restored;
+
+    // Indicates that a copy operation (or move) includes a directory.
+    // Why? Directory creation isn't supported by some roots (like Downloads).
+    // This allows us to restrict available roots to just those with support.
     public boolean directoryCopy;
     public boolean openableOnly;
-    /** Transfer mode for file copy/move operations. */
-    public int transferMode;
+
+    /**
+     * This is basically a sub-type for the copy operation. It can be either COPY or MOVE.
+     * The only legal values are: OPERATION_COPY, OPERATION_MOVE.
+     */
+    public @OpType int copyOperationSubType;
 
     /** Current user navigation stack; empty implies recents. */
     public DocumentStack stack = new DocumentStack();
     private boolean mStackTouched;
+    private boolean mInitialRootChanged;
+    private boolean mInitialDocChanged;
 
     /** Currently active search, overriding any stack. */
     public String currentSearch;
@@ -92,8 +109,11 @@
     /** Instance state for every shown directory */
     public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>();
 
+    /** UI selection */
+    public Selection selectedDocuments = new Selection();
+
     /** Currently copying file */
-    public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
+    public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<>();
 
     /** Name of the package that started DocsUI */
     public List<String> excludedAuthorities = new ArrayList<>();
@@ -108,22 +128,32 @@
     }
 
     public void onRootChanged(RootInfo root) {
+        if (DEBUG) Log.d(TAG, "Root changed to: " + root);
+        if (!mInitialRootChanged && stack.root != null && !root.equals(stack.root)) {
+            mInitialRootChanged = true;
+        }
         stack.root = root;
         stack.clear();
         mStackTouched = true;
     }
 
     public void pushDocument(DocumentInfo info) {
+        if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info);
+        if (!mInitialDocChanged && stack.size() > 0 && !info.equals(stack.peek())) {
+            mInitialDocChanged = true;
+        }
         stack.push(info);
         mStackTouched = true;
     }
 
     public void popDocument() {
+        if (DEBUG) Log.d(TAG, "Popping doc off stack.");
         stack.pop();
         mStackTouched = true;
     }
 
     public void setStack(DocumentStack stack) {
+        if (DEBUG) Log.d(TAG, "Setting the whole darn stack to: " + stack);
         this.stack = stack;
         mStackTouched = true;
     }
@@ -132,6 +162,10 @@
         return mStackTouched;
     }
 
+    public boolean initialLocationHasChanged() {
+        return mInitialRootChanged || mInitialDocChanged;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -152,10 +186,13 @@
         DurableUtils.writeToParcel(out, stack);
         out.writeString(currentSearch);
         out.writeMap(dirState);
+        out.writeParcelable(selectedDocuments, 0);
         out.writeList(selectedDocumentsForCopy);
         out.writeList(excludedAuthorities);
         out.writeInt(openableOnly ? 1 : 0);
         out.writeInt(mStackTouched ? 1 : 0);
+        out.writeInt(mInitialRootChanged ? 1 : 0);
+        out.writeInt(mInitialDocChanged ? 1 : 0);
     }
 
     public static final ClassLoaderCreator<State> CREATOR = new ClassLoaderCreator<State>() {
@@ -180,10 +217,13 @@
             DurableUtils.readFromParcel(in, state.stack);
             state.currentSearch = in.readString();
             in.readMap(state.dirState, loader);
+            state.selectedDocuments = in.readParcelable(loader);
             in.readList(state.selectedDocumentsForCopy, loader);
             in.readList(state.excludedAuthorities, loader);
             state.openableOnly = in.readInt() != 0;
             state.mStackTouched = in.readInt() != 0;
+            state.mInitialRootChanged = in.readInt() != 0;
+            state.mInitialDocChanged = in.readInt() != 0;
             return state;
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 70bee3c..0c851c8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -27,6 +27,7 @@
 import static com.android.internal.util.Preconditions.checkState;
 import static com.google.common.base.Preconditions.checkArgument;
 
+import android.annotation.IntDef;
 import android.annotation.StringRes;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -53,9 +54,7 @@
 import android.support.design.widget.Snackbar;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
-import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.LayoutManager;
 import android.support.v7.widget.RecyclerView.OnItemTouchListener;
 import android.support.v7.widget.RecyclerView.RecyclerListener;
 import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -94,14 +93,19 @@
 import com.android.documentsui.Shared;
 import com.android.documentsui.Snackbars;
 import com.android.documentsui.State;
+import com.android.documentsui.State.ViewMode;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.RootInfo;
 import com.android.documentsui.services.FileOperationService;
+import com.android.documentsui.services.FileOperationService.OpType;
 import com.android.documentsui.services.FileOperations;
+
 import com.google.common.collect.Lists;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -111,6 +115,13 @@
  */
 public class DirectoryFragment extends Fragment implements DocumentsAdapter.Environment {
 
+    @IntDef(flag = true, value = {
+            TYPE_NORMAL,
+            TYPE_SEARCH,
+            TYPE_RECENT_OPEN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResultType {}
     public static final int TYPE_NORMAL = 1;
     public static final int TYPE_SEARCH = 2;
     public static final int TYPE_RECENT_OPEN = 3;
@@ -120,6 +131,11 @@
     public static final int ANIM_LEAVE = 3;
     public static final int ANIM_ENTER = 4;
 
+    @IntDef(flag = true, value = {
+            REQUEST_COPY_DESTINATION
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestCode {}
     public static final int REQUEST_COPY_DESTINATION = 1;
 
     static final boolean DEBUG_ENABLE_DND = true;
@@ -140,6 +156,7 @@
     private MultiSelectManager mSelectionManager;
     private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
     private ItemEventListener mItemEventListener = new ItemEventListener();
+    private FocusManager mFocusManager;
 
     private IconHelper mIconHelper;
 
@@ -147,7 +164,7 @@
     private RecyclerView mRecView;
     private ListeningGestureDetector mGestureDetector;
 
-    private int mType = TYPE_NORMAL;
+    private @ResultType int mType = TYPE_NORMAL;
     private String mStateKey;
 
     private int mLastSortOrder = SORT_ORDER_UNKNOWN;
@@ -155,9 +172,7 @@
     private LoaderCallbacks<DirectoryResult> mCallbacks;
     private FragmentTuner mTuner;
     private DocumentClipper mClipper;
-    // These are lazily initialized.
-    private LinearLayoutManager mListLayout;
-    private GridLayoutManager mGridLayout;
+    private GridLayoutManager mLayout;
     private int mColumnCount = 1;  // This will get updated when layout changes.
 
     private MessageBar mMessageBar;
@@ -173,7 +188,7 @@
 
         mEmptyView = view.findViewById(android.R.id.empty);
 
-        mRecView = (RecyclerView) view.findViewById(R.id.list);
+        mRecView = (RecyclerView) view.findViewById(R.id.dir_list);
         mRecView.setRecyclerListener(
                 new RecyclerListener() {
                     @Override
@@ -182,22 +197,6 @@
                     }
                 });
 
-        // TODO: Rather than update columns on layout changes, push this
-        // code (or something like it) into GridLayoutManager.
-        mRecView.addOnLayoutChangeListener(
-                new View.OnLayoutChangeListener() {
-
-                    @Override
-                    public void onLayoutChange(
-                            View v, int left, int top, int right, int bottom, int oldLeft,
-                            int oldTop, int oldRight, int oldBottom) {
-                        mColumnCount = calculateColumnCount();
-                        if (mGridLayout != null) {
-                            mGridLayout.setSpanCount(mColumnCount);
-                        }
-                    }
-                });
-
         mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity()));
 
         // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration).
@@ -218,9 +217,6 @@
             final View view = mRecView.getChildAt(i);
             cancelThumbnailTask(view);
         }
-
-        // Clear any outstanding selection
-        mSelectionManager.clearSelection();
     }
 
     @Override
@@ -232,6 +228,7 @@
 
         final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
         final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+        mStateKey = buildStateKey(root, doc);
 
         mIconHelper = new IconHelper(context, MODE_GRID);
 
@@ -240,10 +237,24 @@
 
         mRecView.setAdapter(mAdapter);
 
+        mLayout = new GridLayoutManager(getContext(), mColumnCount);
+        SpanSizeLookup lookup = mAdapter.createSpanSizeLookup();
+        if (lookup != null) {
+            mLayout.setSpanSizeLookup(lookup);
+        }
+        mRecView.setLayoutManager(mLayout);
+
         mGestureDetector = new ListeningGestureDetector(this.getContext(), new GestureListener());
 
         mRecView.addOnItemTouchListener(mGestureDetector);
 
+        // final here because we'll manually bump the listener iwhen we had an initial selection,
+        // but only after the model is fully loaded.
+        final SelectionModeListener selectionListener = new SelectionModeListener();
+        final Selection initialSelection = state.selectedDocuments.hasDirectoryKey(mStateKey)
+            ? state.selectedDocuments
+            : null;
+
         // TODO: instead of inserting the view into the constructor, extract listener-creation code
         // and set the listener on the view after the fact.  Then the view doesn't need to be passed
         // into the selection manager.
@@ -252,17 +263,21 @@
                 mAdapter,
                 state.allowMultiple
                     ? MultiSelectManager.MODE_MULTIPLE
-                    : MultiSelectManager.MODE_SINGLE);
-        mSelectionManager.addCallback(new SelectionModeListener());
+                    : MultiSelectManager.MODE_SINGLE,
+                initialSelection);
+
+        mSelectionManager.addCallback(selectionListener);
+
+        // Make sure this is done after the RecyclerView is set up.
+        mFocusManager = new FocusManager(mRecView);
 
         mModel = new Model();
         mModel.addUpdateListener(mAdapter);
         mModel.addUpdateListener(mModelUpdateListener);
 
         mType = getArguments().getInt(EXTRA_TYPE);
-        mStateKey = buildStateKey(root, doc);
 
-        mTuner = FragmentTuner.pick(state);
+        mTuner = FragmentTuner.pick(getContext(), state);
         mClipper = new DocumentClipper(context);
 
         boolean hideGridTitles;
@@ -320,10 +335,8 @@
 
                 updateDisplayState();
 
-                // When launched into empty recents, show drawer
-                if (mType == TYPE_RECENT_OPEN && mModel.isEmpty() && !state.hasLocationChanged() &&
-                        context instanceof DocumentsActivity) {
-                    ((DocumentsActivity) context).setRootsDrawerOpen(true);
+                if (initialSelection != null) {
+                    selectionListener.onSelectionChanged();
                 }
 
                 // Restore any previous instance state
@@ -338,6 +351,8 @@
                 }
 
                 mLastSortOrder = state.derivedSortOrder;
+
+                mTuner.onModelLoaded(mModel, mType);
             }
 
             @Override
@@ -351,19 +366,36 @@
     }
 
     @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        // There's only one request code right now. Replace this with a switch statement or
-        // something more scalable when more codes are added.
-        if (requestCode != REQUEST_COPY_DESTINATION) {
-            return;
+    public void onSaveInstanceState(Bundle outState) {
+        State state = getDisplayState();
+        if (mSelectionManager.hasSelection()) {
+            mSelectionManager.getSelection(state.selectedDocuments);
+            state.selectedDocuments.setDirectoryKey(mStateKey);
+            if (!state.selectedDocuments.isEmpty()) {
+                if (DEBUG) Log.d(TAG, "Persisted selection: " + state.selectedDocuments);
+            }
         }
+    }
+
+    @Override
+    public void onActivityResult(@RequestCode int requestCode, int resultCode, Intent data) {
+        switch(requestCode) {
+            case REQUEST_COPY_DESTINATION:
+                handleCopyResult(resultCode, data);
+                break;
+            default:
+                throw new UnsupportedOperationException("Unknown request code: " + requestCode);
+        }
+    }
+
+    private void handleCopyResult(int resultCode, Intent data) {
         if (resultCode == Activity.RESULT_CANCELED || data == null) {
             // User pressed the back button or otherwise cancelled the destination pick. Don't
             // proceed with the copy.
             return;
         }
 
-        int operationType = data.getIntExtra(
+        @OpType int operationType = data.getIntExtra(
                 FileOperationService.EXTRA_OPERATION,
                 FileOperationService.OPERATION_COPY);
 
@@ -432,41 +464,28 @@
     }
 
     /**
-     * Returns a {@code LayoutManager} for {@code mode}, lazily initializing
-     * classes as needed.
+     * Updates the layout after the view mode switches.
+     * @param mode The new view mode.
      */
-    private void updateLayout(int mode) {
-        final LayoutManager layout;
-        switch (mode) {
-            case MODE_GRID:
-                if (mGridLayout == null) {
-                    mGridLayout = new GridLayoutManager(getContext(), mColumnCount);
-                    SpanSizeLookup lookup = mAdapter.createSpanSizeLookup();
-                    if (lookup != null) {
-                        mGridLayout.setSpanSizeLookup(lookup);
-                    }
-                }
-                layout = mGridLayout;
-                break;
-            case MODE_LIST:
-                if (mListLayout == null) {
-                    mListLayout = new LinearLayoutManager(getContext());
-                }
-                layout = mListLayout;
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported layout mode: " + mode);
+    private void updateLayout(@ViewMode int mode) {
+        mColumnCount = calculateColumnCount(mode);
+        if (mLayout != null) {
+            mLayout.setSpanCount(mColumnCount);
         }
 
         int pad = getDirectoryPadding(mode);
         mRecView.setPadding(pad, pad, pad, pad);
-        // setting layout manager automatically invalidates existing ViewHolders.
-        mRecView.setLayoutManager(layout);
+        mRecView.requestLayout();
         mSelectionManager.handleLayoutChanged();  // RecyclerView doesn't do this for us
         mIconHelper.setViewMode(mode);
     }
 
-    private int calculateColumnCount() {
+    private int calculateColumnCount(@ViewMode int mode) {
+        if (mode == MODE_LIST) {
+            // List mode is a "grid" with 1 column.
+            return 1;
+        }
+
         int cellWidth = getResources().getDimensionPixelSize(R.dimen.grid_width);
         int cellMargin = 2 * getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
         int viewPadding = mRecView.getPaddingLeft() + mRecView.getPaddingRight();
@@ -478,14 +497,12 @@
         return columnCount;
     }
 
-    private int getDirectoryPadding(int mode) {
+    private int getDirectoryPadding(@ViewMode int mode) {
         switch (mode) {
             case MODE_GRID:
-                return getResources().getDimensionPixelSize(
-                        R.dimen.grid_container_padding);
+                return getResources().getDimensionPixelSize(R.dimen.grid_container_padding);
             case MODE_LIST:
-                return getResources().getDimensionPixelSize(
-                        R.dimen.list_container_padding);
+                return getResources().getDimensionPixelSize(R.dimen.list_container_padding);
             default:
                 throw new IllegalArgumentException("Unsupported layout mode: " + mode);
         }
@@ -525,7 +542,11 @@
         @Override
         public void onItemStateChanged(String modelId, boolean selected) {
             final Cursor cursor = mModel.getItem(modelId);
-            checkNotNull(cursor, "Cursor cannot be null.");
+            if (cursor == null) {
+                Log.e(TAG, "Model returned null cursor for document: " + modelId
+                        + ". Ignoring state changed event.");
+                return;
+            }
 
             // TODO: Should this be happening in onSelectionChanged? Technically this callback is
             // triggered on "silent" selection updates (i.e. we might be reacting to unfinalized
@@ -784,7 +805,7 @@
                 .show();
     }
 
-    private void transferDocuments(final Selection selected, final int mode) {
+    private void transferDocuments(final Selection selected, final @OpType int mode) {
         // Pop up a dialog to pick a destination.  This is inadequate but works for now.
         // TODO: Implement a picker that is to spec.
         final Intent intent = new Intent(
@@ -793,25 +814,43 @@
                 getActivity(),
                 DocumentsActivity.class);
 
+        // Set an appropriate title on the drawer when it is shown in the picker.
+        // Coupled with the fact that we auto-open the drawer for copy/move operations
+        // it should basically be the thing people see first.
+        int drawerTitleId = mode == FileOperationService.OPERATION_MOVE
+                ? R.string.menu_move : R.string.menu_copy;
+        intent.putExtra(DocumentsContract.EXTRA_PROMPT, getResources().getString(drawerTitleId));
+
         new GetDocumentsTask() {
             @Override
             void onDocumentsReady(List<DocumentInfo> docs) {
+                // TODO: Can this move to Fragment bundle state?
                 getDisplayState().selectedDocumentsForCopy = docs;
 
-                boolean directoryCopy = false;
-                for (DocumentInfo info : docs) {
-                    if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
-                        directoryCopy = true;
-                        break;
-                    }
-                }
-                intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, directoryCopy);
+                // Determine if there is a directory in the set of documents
+                // to be copied? Why? Directory creation isn't supported by some roots
+                // (like Downloads). This informs DocumentsActivity (the "picker")
+                // to restrict available roots to just those with support.
+                intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, hasDirectory(docs));
                 intent.putExtra(FileOperationService.EXTRA_OPERATION, mode);
+
+                // This just identifies the type of request...we'll check it
+                // when we reveive a response.
                 startActivityForResult(intent, REQUEST_COPY_DESTINATION);
             }
+
         }.execute(selected);
     }
 
+    private static boolean hasDirectory(List<DocumentInfo> docs) {
+        for (DocumentInfo info : docs) {
+            if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void renameDocuments(Selection selected) {
         // Batch renaming not supported
         // Rename option is only available in menu when 1 document selected
@@ -828,6 +867,7 @@
     @Override
     public void initDocumentHolder(DocumentHolder holder) {
         holder.addEventListener(mItemEventListener);
+        holder.itemView.setOnFocusChangeListener(mFocusManager);
     }
 
     @Override
@@ -876,22 +916,15 @@
         msgView.setText(msg);
         imageView.setImageResource(drawable);
 
-        content.animate().cancel();  // cancel any ongoing animations
-
-        content.setAlpha(0);
         mEmptyView.setVisibility(View.VISIBLE);
+        mEmptyView.requestFocus();
         mRecView.setVisibility(View.GONE);
-
-        // fade in the content, so it looks purdy like
-        content.animate()
-                .alpha(1f)
-                .setDuration(EMPTY_REVEAL_DURATION)
-                .setListener(null);
     }
 
     private void showDirectory() {
         mEmptyView.setVisibility(View.GONE);
         mRecView.setVisibility(View.VISIBLE);
+        mRecView.requestFocus();
     }
 
     private String findCommonMimeType(List<String> mimeTypes) {
@@ -1057,6 +1090,13 @@
         }
     }
 
+    /**
+     * Attempts to restore focus on the directory listing.
+     */
+    public void requestFocus() {
+        mFocusManager.restoreLastFocus();
+    }
+
     private void setupDragAndDropOnDirectoryView(View view) {
         // Listen for drops on non-directory items and empty space.
         view.setOnDragListener(mOnDragListener);
@@ -1255,119 +1295,38 @@
                 return false;
             }
 
-            boolean handled = false;
-            if (Events.isNavigationKeyCode(keyCode)) {
-                // Find the target item and focus it.
-                int endPos = findTargetPosition(doc.itemView, keyCode);
-
-                if (endPos != RecyclerView.NO_POSITION) {
-                    focusItem(endPos);
-
-                    // Handle any necessary adjustments to selection.
-                    boolean extendSelection = event.isShiftPressed();
-                    if (extendSelection) {
-                        int startPos = doc.getAdapterPosition();
-                        mSelectionManager.selectRange(startPos, endPos);
+            if (mFocusManager.handleKey(doc, keyCode, event)) {
+                // Handle range selection adjustments. Extending the selection will adjust the
+                // bounds of the in-progress range selection. Each time an unshifted navigation
+                // event is received, the range selection is restarted.
+                if (shouldExtendSelection(event)) {
+                    if (!mSelectionManager.isRangeSelectionActive()) {
+                        // Start a range selection if one isn't active
+                        mSelectionManager.startRangeSelection(doc.getAdapterPosition());
                     }
-                    handled = true;
+                    mSelectionManager.snapRangeSelection(mFocusManager.getFocusPosition());
+                } else {
+                    mSelectionManager.endRangeSelection();
                 }
-            } else {
-                // Handle enter key events
-                if (keyCode == KeyEvent.KEYCODE_ENTER) {
-                    handled = onActivate(doc);
+                return true;
+            }
+
+            // Handle enter key events
+            if (keyCode == KeyEvent.KEYCODE_ENTER) {
+                if (event.isShiftPressed()) {
+                    return onSelect(doc);
+                } else {
+                    return onActivate(doc);
                 }
             }
 
-            return handled;
+            return false;
         }
 
-        /**
-         * Finds the destination position where the focus should land for a given navigation event.
-         *
-         * @param view The view that received the event.
-         * @param keyCode The key code for the event.
-         * @return The adapter position of the destination item. Could be RecyclerView.NO_POSITION.
-         */
-        private int findTargetPosition(View view, int keyCode) {
-            if (keyCode == KeyEvent.KEYCODE_MOVE_HOME) {
-                return 0;
-            }
-
-            if (keyCode == KeyEvent.KEYCODE_MOVE_END) {
-                return mAdapter.getItemCount() - 1;
-            }
-
-            // Find a navigation target based on the arrow key that the user pressed.
-            int searchDir = -1;
-            switch (keyCode) {
-                case KeyEvent.KEYCODE_DPAD_UP:
-                    searchDir = View.FOCUS_UP;
-                    break;
-                case KeyEvent.KEYCODE_DPAD_DOWN:
-                    searchDir = View.FOCUS_DOWN;
-                    break;
-                case KeyEvent.KEYCODE_DPAD_LEFT:
-                    searchDir = View.FOCUS_LEFT;
-                    break;
-                case KeyEvent.KEYCODE_DPAD_RIGHT:
-                    searchDir = View.FOCUS_RIGHT;
-                    break;
-            }
-
-            if (searchDir != -1) {
-                View targetView = view.focusSearch(searchDir);
-                // TargetView can be null, for example, if the user pressed <down> at the bottom
-                // of the list.
-                if (targetView != null) {
-                    // Ignore navigation targets that aren't items in the RecyclerView.
-                    if (targetView.getParent() == mRecView) {
-                        return mRecView.getChildAdapterPosition(targetView);
-                    }
-                }
-            }
-
-            return RecyclerView.NO_POSITION;
+        private boolean shouldExtendSelection(KeyEvent event) {
+            return Events.isNavigationKeyCode(event.getKeyCode()) &&
+                    event.isShiftPressed();
         }
-
-        /**
-         * Requests focus for the item in the given adapter position, scrolling the RecyclerView if
-         * necessary.
-         *
-         * @param pos
-         */
-        public void focusItem(final int pos) {
-            // If the item is already in view, focus it; otherwise, scroll to it and focus it.
-            RecyclerView.ViewHolder vh = mRecView.findViewHolderForAdapterPosition(pos);
-            if (vh != null) {
-                vh.itemView.requestFocus();
-            } else {
-                mRecView.smoothScrollToPosition(pos);
-                // Set a one-time listener to request focus when the scroll has completed.
-                mRecView.addOnScrollListener(
-                    new RecyclerView.OnScrollListener() {
-                        @Override
-                        public void onScrollStateChanged (RecyclerView view, int newState) {
-                            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-                                // When scrolling stops, find the item and focus it.
-                                RecyclerView.ViewHolder vh =
-                                        view.findViewHolderForAdapterPosition(pos);
-                                if (vh != null) {
-                                    vh.itemView.requestFocus();
-                                } else {
-                                    // This might happen in weird corner cases, e.g. if the user is
-                                    // scrolling while a delete operation is in progress.  In that
-                                    // case, just don't attempt to focus the missing item.
-                                    Log.w(
-                                        TAG, "Unable to focus position " + pos + " after a scroll");
-                                }
-                                view.removeOnScrollListener(this);
-                            }
-                        }
-                    });
-            }
-        }
-
-
     }
 
     private final class ModelUpdateListener implements Model.UpdateListener {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
index 43c2f63..0930c22 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentsAdapter.java
@@ -27,7 +27,6 @@
 
 import com.android.documentsui.State;
 
-import java.nio.channels.UnsupportedAddressTypeException;
 import java.util.List;
 
 /**
@@ -87,7 +86,7 @@
      * we adjust sizes.
      */
     GridLayoutManager.SpanSizeLookup createSpanSizeLookup() {
-        throw new UnsupportedAddressTypeException();
+        throw new UnsupportedOperationException();
     }
 
     static boolean isDirectory(Cursor cursor) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java
new file mode 100644
index 0000000..e90a447
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FocusManager.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.View;
+
+import com.android.documentsui.Events;
+
+/**
+ * A class that handles navigation and focus within the DirectoryFragment.
+ */
+class FocusManager implements View.OnFocusChangeListener {
+    private static final String TAG = "FocusManager";
+
+    private RecyclerView mView;
+    private RecyclerView.Adapter<?> mAdapter;
+    private GridLayoutManager mLayout;
+
+    private int mLastFocusPosition = RecyclerView.NO_POSITION;
+
+    public FocusManager(RecyclerView view) {
+        mView = view;
+        mAdapter = view.getAdapter();
+        mLayout = (GridLayoutManager) view.getLayoutManager();
+    }
+
+    /**
+     * Handles navigation (setting focus, adjusting selection if needed) arising from incoming key
+     * events.
+     *
+     * @param doc The DocumentHolder receiving the key event.
+     * @param keyCode
+     * @param event
+     * @return Whether the event was handled.
+     */
+    public boolean handleKey(DocumentHolder doc, int keyCode, KeyEvent event) {
+        boolean extendSelection = false;
+        // Translate space/shift-space into PgDn/PgUp
+        if (keyCode == KeyEvent.KEYCODE_SPACE) {
+            if (event.isShiftPressed()) {
+                keyCode = KeyEvent.KEYCODE_PAGE_UP;
+            } else {
+                keyCode = KeyEvent.KEYCODE_PAGE_DOWN;
+            }
+        } else {
+            extendSelection = event.isShiftPressed();
+        }
+
+        if (Events.isNavigationKeyCode(keyCode)) {
+            // Find the target item and focus it.
+            int endPos = findTargetPosition(doc.itemView, keyCode, event);
+
+            if (endPos != RecyclerView.NO_POSITION) {
+                focusItem(endPos);
+            }
+            // Swallow all navigation keystrokes. Otherwise they go to the app's global
+            // key-handler, which will route them back to the DF and cause focus to be reset.
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void onFocusChange(View v, boolean hasFocus) {
+        // Remember focus events on items.
+        if (hasFocus && v.getParent() == mView) {
+            mLastFocusPosition = mView.getChildAdapterPosition(v);
+        }
+    }
+
+    /**
+     * Requests focus on the item that last had focus. Scrolls to that item if necessary.
+     */
+    public void restoreLastFocus() {
+        if (mLastFocusPosition != RecyclerView.NO_POSITION) {
+            // The system takes care of situations when a view is no longer on screen, etc,
+            focusItem(mLastFocusPosition);
+        } else {
+            // Focus the first visible item
+            focusItem(mLayout.findFirstVisibleItemPosition());
+        }
+    }
+
+    /**
+     * @return The adapter position of the last focused item.
+     */
+    public int getFocusPosition() {
+        return mLastFocusPosition;
+    }
+
+    /**
+     * Finds the destination position where the focus should land for a given navigation event.
+     *
+     * @param view The view that received the event.
+     * @param keyCode The key code for the event.
+     * @param event
+     * @return The adapter position of the destination item. Could be RecyclerView.NO_POSITION.
+     */
+    private int findTargetPosition(View view, int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MOVE_HOME:
+                return 0;
+            case KeyEvent.KEYCODE_MOVE_END:
+                return mAdapter.getItemCount() - 1;
+            case KeyEvent.KEYCODE_PAGE_UP:
+            case KeyEvent.KEYCODE_PAGE_DOWN:
+                return findPagedTargetPosition(view, keyCode, event);
+        }
+
+        // Find a navigation target based on the arrow key that the user pressed.
+        int searchDir = -1;
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_UP:
+                searchDir = View.FOCUS_UP;
+                break;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                searchDir = View.FOCUS_DOWN;
+                break;
+        }
+
+        if (inGridMode()) {
+            int currentPosition = mView.getChildAdapterPosition(view);
+            // Left and right arrow keys only work in grid mode.
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                    if (currentPosition > 0) {
+                        // Stop backward focus search at the first item, otherwise focus will wrap
+                        // around to the last visible item.
+                        searchDir = View.FOCUS_BACKWARD;
+                    }
+                    break;
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                    if (currentPosition < mAdapter.getItemCount() - 1) {
+                        // Stop forward focus search at the last item, otherwise focus will wrap
+                        // around to the first visible item.
+                        searchDir = View.FOCUS_FORWARD;
+                    }
+                    break;
+            }
+        }
+
+        if (searchDir != -1) {
+            // Focus search behaves badly if the parent RecyclerView is focused. However, focusable
+            // shouldn't be unset on RecyclerView, otherwise focus isn't properly restored after
+            // events that cause a UI rebuild (like rotating the device). Compromise: turn focusable
+            // off while performing the focus search.
+            // TODO: Revisit this when RV focus issues are resolved.
+            mView.setFocusable(false);
+            View targetView = view.focusSearch(searchDir);
+            mView.setFocusable(true);
+            // TargetView can be null, for example, if the user pressed <down> at the bottom
+            // of the list.
+            if (targetView != null) {
+                // Ignore navigation targets that aren't items in the RecyclerView.
+                if (targetView.getParent() == mView) {
+                    return mView.getChildAdapterPosition(targetView);
+                }
+            }
+        }
+
+        return RecyclerView.NO_POSITION;
+    }
+
+    /**
+     * Given a PgUp/PgDn event and the current view, find the position of the target view.
+     * This returns:
+     * <li>The position of the topmost (or bottom-most) visible item, if the current item is not
+     *     the top- or bottom-most visible item.
+     * <li>The position of an item that is one page's worth of items up (or down) if the current
+     *      item is the top- or bottom-most visible item.
+     * <li>The first (or last) item, if paging up (or down) would go past those limits.
+     * @param view The view that received the key event.
+     * @param keyCode Must be KEYCODE_PAGE_UP or KEYCODE_PAGE_DOWN.
+     * @param event
+     * @return The adapter position of the target item.
+     */
+    private int findPagedTargetPosition(View view, int keyCode, KeyEvent event) {
+        int first = mLayout.findFirstVisibleItemPosition();
+        int last = mLayout.findLastVisibleItemPosition();
+        int current = mView.getChildAdapterPosition(view);
+        int pageSize = last - first + 1;
+
+        if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
+            if (current > first) {
+                // If the current item isn't the first item, target the first item.
+                return first;
+            } else {
+                // If the current item is the first item, target the item one page up.
+                int target = current - pageSize;
+                return target < 0 ? 0 : target;
+            }
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
+            if (current < last) {
+                // If the current item isn't the last item, target the last item.
+                return last;
+            } else {
+                // If the current item is the last item, target the item one page down.
+                int target = current + pageSize;
+                int max = mAdapter.getItemCount() - 1;
+                return target < max ? target : max;
+            }
+        }
+
+        throw new IllegalArgumentException("Unsupported keyCode: " + keyCode);
+    }
+
+    /**
+     * Requests focus for the item in the given adapter position, scrolling the RecyclerView if
+     * necessary.
+     *
+     * @param pos
+     */
+    private void focusItem(final int pos) {
+        // If the item is already in view, focus it; otherwise, scroll to it and focus it.
+        RecyclerView.ViewHolder vh = mView.findViewHolderForAdapterPosition(pos);
+        if (vh != null) {
+            vh.itemView.requestFocus();
+        } else {
+            mView.smoothScrollToPosition(pos);
+            // Set a one-time listener to request focus when the scroll has completed.
+            mView.addOnScrollListener(
+                    new RecyclerView.OnScrollListener() {
+                        @Override
+                        public void onScrollStateChanged(RecyclerView view, int newState) {
+                            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+                                // When scrolling stops, find the item and focus it.
+                                RecyclerView.ViewHolder vh =
+                                        view.findViewHolderForAdapterPosition(pos);
+                                if (vh != null) {
+                                    vh.itemView.requestFocus();
+                                } else {
+                                    // This might happen in weird corner cases, e.g. if the user is
+                                    // scrolling while a delete operation is in progress. In that
+                                    // case, just don't attempt to focus the missing item.
+                                    Log.w(TAG, "Unable to focus position " + pos + " after scroll");
+                                }
+                                view.removeOnScrollListener(this);
+                            }
+                        }
+                    });
+        }
+    }
+
+    /**
+     * @return Whether the layout manager is currently in a grid-configuration.
+     */
+    private boolean inGridMode() {
+        return mLayout.getSpanCount() > 1;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index a295ab2..a9b0fd1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -16,6 +16,7 @@
 
 package com.android.documentsui.dirlist;
 
+import static com.android.documentsui.Shared.DEBUG;
 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;
@@ -24,15 +25,20 @@
 import static com.android.documentsui.State.ACTION_OPEN_TREE;
 import static com.android.internal.util.Preconditions.checkArgument;
 
+import android.content.Context;
+import android.os.SystemProperties;
+import android.provider.DocumentsContract.Document;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.android.documentsui.DocumentsActivity;
+import com.android.documentsui.FilesActivity;
 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;
+import com.android.documentsui.dirlist.DirectoryFragment.ResultType;
 
 /**
  * Providers support for specializing the DirectoryFragment to the "host" Activity.
@@ -40,20 +46,22 @@
  */
 public abstract class FragmentTuner {
 
+    final Context mContext;
     final State mState;
 
-    public FragmentTuner(State state) {
+    public FragmentTuner(Context context, State state) {
+        mContext = context;
         mState = state;
     }
 
-    public static FragmentTuner pick(State state) {
+    public static FragmentTuner pick(Context context, State state) {
         switch (state.action) {
             case ACTION_BROWSE:
-                return new FilesTuner(state);
+                return new FilesTuner(context, state);
             case ACTION_MANAGE:
-                return new DownloadsTuner(state);
+                return new DownloadsTuner(context, state);
             default:
-                return new DocumentsTuner(state);
+                return new DocumentsTuner(context, state);
         }
     }
 
@@ -76,13 +84,15 @@
         return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
     }
 
+    abstract void onModelLoaded(Model model, @ResultType int resultType);
+
     /**
      * Provides support for Platform specific specializations of DirectoryFragment.
      */
     private static final class DocumentsTuner extends FragmentTuner {
 
-        public DocumentsTuner(State state) {
-            super(state);
+        public DocumentsTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -154,6 +164,16 @@
             moveTo.setEnabled(moveEnabled);
             rename.setVisible(false);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {
+            // When launched into empty recents, show drawer
+            if (resultType == DirectoryFragment.TYPE_RECENT_OPEN
+                    && model.isEmpty()
+                    && !mState.hasLocationChanged()) {
+                ((DocumentsActivity) mContext).setRootsDrawerOpen(true);
+            }
+        }
     }
 
     /**
@@ -161,8 +181,8 @@
      */
     private static final class DownloadsTuner extends FragmentTuner {
 
-        public DownloadsTuner(State state) {
-            super(state);
+        public DownloadsTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -189,6 +209,9 @@
             moveTo.setEnabled(moveEnabled);
             rename.setVisible(false);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {}
     }
 
     /**
@@ -196,8 +219,10 @@
      */
     private static final class FilesTuner extends FragmentTuner {
 
-        public FilesTuner(State state) {
-            super(state);
+        private static final String TAG = "FilesTuner";
+
+        public FilesTuner(Context context, State state) {
+            super(context, state);
         }
 
         @Override
@@ -221,9 +246,24 @@
 
             Menus.disableHiddenItems(menu, copy, paste);
         }
+
+        @Override
+        void onModelLoaded(Model model, @ResultType int resultType) {
+            if (DEBUG) Log.d(TAG, "Handling model loaded. Has Location shcnage: " + mState.initialLocationHasChanged());
+            // When launched into empty root, open drawer.
+            if (model.isEmpty() && !mState.initialLocationHasChanged()
+                    && resultType != DirectoryFragment.TYPE_SEARCH) {
+                if (DEBUG) Log.d(TAG, "Showing roots drawer cuz stuffs empty.");
+
+                // This noops on layouts without drawer, so no need to guard.
+                ((FilesActivity) mContext).setRootsDrawerOpen(true);
+            }
+            if (DEBUG) Log.d(TAG, "Donezo.");
+        }
     }
 
     private static boolean isDirectory(String mimeType) {
         return Document.MIME_TYPE_DIR.equals(mimeType);
     }
+
 }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
index c4ac0f5..055adc6a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java
@@ -100,10 +100,9 @@
         mIconThumb.animate().cancel();
         mIconThumb.setAlpha(0f);
 
-        mIconMimeSm.setImageDrawable(IconUtils.loadMimeIcon(mContext, docMimeType));
-
         final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
-        mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMimeLg);
+        mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMimeLg,
+                mIconMimeSm);
 
         if (mHideTitles) {
             mTitle.setVisibility(View.GONE);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
index 53ed62e..ff0f4b1 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/IconHelper.java
@@ -32,6 +32,7 @@
 import android.os.OperationCanceledException;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
 import android.util.Log;
 import android.widget.ImageView;
 
@@ -199,11 +200,12 @@
      * @param docFlags Flags for the file being represented.
      * @param docIcon Custom icon (if any) for the file being requested.
      * @param iconThumb The itemview's thumbnail icon.
-     * @param iconMime The itemview's mime icon.
+     * @param iconMime The itemview's mime icon. Hidden when iconThumb is shown.
+     * @param subIconMime The second itemview's mime icon. Always visible.
      * @return
      */
     public void loadThumbnail(Uri uri, String mimeType, int docFlags, int docIcon,
-            ImageView iconThumb, ImageView iconMime) {
+            ImageView iconThumb, ImageView iconMime, @Nullable ImageView subIconMime) {
         boolean cacheHit = false;
 
         final String docAuthority = uri.getAuthority();
@@ -225,6 +227,12 @@
             }
         }
 
+        final Drawable icon = getDocumentIcon(mContext, docAuthority,
+                DocumentsContract.getDocumentId(uri), mimeType, docIcon);
+        if (subIconMime != null) {
+            subIconMime.setImageDrawable(icon);
+        }
+
         if (cacheHit) {
             iconMime.setImageDrawable(null);
             iconMime.setAlpha(0f);
@@ -232,8 +240,7 @@
         } else {
             // Add a mime icon if the thumbnail is being loaded in the background.
             iconThumb.setImageDrawable(null);
-            iconMime.setImageDrawable(getDocumentIcon(
-                    mContext, docAuthority, DocumentsContract.getDocumentId(uri), mimeType, docIcon));
+            iconMime.setImageDrawable(icon);
             iconMime.setAlpha(1f);
             iconThumb.setAlpha(0f);
         }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
index 00ea27b..8c3b53c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java
@@ -101,7 +101,7 @@
         mIconThumb.setAlpha(0f);
 
         final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
-        mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMime);
+        mIconHelper.loadThumbnail(uri, docMimeType, docFlags, docIcon, mIconThumb, mIconMime, null);
 
         mTitle.setText(docDisplayName);
         mTitle.setVisibility(View.VISIBLE);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
index 075b3ea..3a45995 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java
@@ -33,7 +33,6 @@
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
-import com.android.documentsui.BaseActivity.SiblingProvider;
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.RootCursorWrapper;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
@@ -48,7 +47,7 @@
  * The data model for the current loaded directory.
  */
 @VisibleForTesting
-public class Model implements SiblingProvider {
+public class Model {
     private static final String TAG = "Model";
 
     private boolean mIsLoading;
@@ -358,7 +357,7 @@
         return (l == -1) ? Long.MAX_VALUE : l;
     }
 
-    @Nullable Cursor getItem(String modelId) {
+    public @Nullable Cursor getItem(String modelId) {
         Integer pos = mPositions.get(modelId);
         if (pos != null) {
             mCursor.moveToPosition(pos);
@@ -388,14 +387,6 @@
         return docs;
     }
 
-    @Override
-    public Cursor getCursor() {
-        if (Looper.myLooper() != Looper.getMainLooper()) {
-            throw new IllegalStateException("Can't call getCursor from non-main thread.");
-        }
-        return mCursor;
-    }
-
     void addUpdateListener(UpdateListener listener) {
         mUpdateListeners.add(listener);
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
index 516b25e..c8b6f85 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -23,9 +23,12 @@
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
+import android.annotation.IntDef;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.GridLayoutManager;
@@ -41,12 +44,13 @@
 import com.android.documentsui.Events.MotionInputEvent;
 import com.android.documentsui.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -58,10 +62,13 @@
  */
 public final class MultiSelectManager {
 
-    /** Selection mode for multiple select. **/
+    @IntDef(flag = true, value = {
+            MODE_MULTIPLE,
+            MODE_SINGLE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SelectionMode {}
     public static final int MODE_MULTIPLE = 0;
-
-    /** Selection mode for multiple select. **/
     public static final int MODE_SINGLE = 1;
 
     private static final String TAG = "MultiSelectManager";
@@ -79,14 +86,19 @@
 
 
     /**
-     * @param recyclerView
-     * @param mode Selection mode
+     * @param mode Selection single or multiple selection mode.
+     * @param initialSelection selection state probably preserved in external state.
      */
     public MultiSelectManager(
-            final RecyclerView recyclerView, DocumentsAdapter adapter, int mode) {
-        this(new RuntimeSelectionEnvironment(recyclerView), adapter, mode);
+            final RecyclerView recyclerView,
+            DocumentsAdapter adapter,
+            @SelectionMode int mode,
+            @Nullable Selection initialSelection) {
+
+        this(new RuntimeSelectionEnvironment(recyclerView), adapter, mode, initialSelection);
 
         if (mode == MODE_MULTIPLE) {
+            // TODO: Don't load this on low memory devices.
             mBandManager = new BandController();
         }
 
@@ -116,10 +128,18 @@
      * @hide
      */
     @VisibleForTesting
-    MultiSelectManager(SelectionEnvironment environment, DocumentsAdapter adapter, int mode) {
+    MultiSelectManager(
+            SelectionEnvironment environment,
+            DocumentsAdapter adapter,
+            @SelectionMode int mode,
+            @Nullable Selection initialSelection) {
+
         mEnvironment = checkNotNull(environment, "'environment' cannot be null.");
         mAdapter = checkNotNull(adapter, "'adapter' cannot be null.");
         mSingleSelect = mode == MODE_SINGLE;
+        if (initialSelection != null) {
+            mSelection.copyFrom(initialSelection);
+        }
 
         mAdapter.registerAdapterDataObserver(
                 new RecyclerView.AdapterDataObserver() {
@@ -203,6 +223,13 @@
     }
 
     /**
+     * Updates selection to include items in {@code selection}.
+     */
+    public void updateSelection(Selection selection) {
+        setItemsSelected(selection.toList(), true);
+    }
+
+    /**
      * Sets the selected state of the specified items. Note that the callback will NOT
      * be consulted to see if an item can be selected.
      *
@@ -343,39 +370,41 @@
     }
 
     /**
-     * Handle a range selection event.
-     * <li> If the MSM is currently in single-select mode, only the last item in the range will
-     * actually be selected.
-     * <li>If a range selection is not already active, one will be started, and the given range of
-     * items will be selected.  The given startPos becomes the anchor for the range selection.
-     * <li>If a range selection is already active, the anchor is not changed. The range is extended
-     * from its current anchor to endPos.
+     * Starts a range selection. If a range selection is already active, this will start a new range
+     * selection (which will reset the range anchor).
      *
-     * @param startPos
-     * @param endPos
+     * @param pos The anchor position for the selection range.
      */
-    public void selectRange(int startPos, int endPos) {
-        // In single-select mode, just select the last item in the range.
-        if (mSingleSelect) {
-            attemptSelect(mAdapter.getModelId(endPos));
-            return;
-        }
+    void startRangeSelection(int pos) {
+      attemptSelect(mAdapter.getModelId(pos));
+      setSelectionRangeBegin(pos);
+    }
 
-        // In regular (i.e. multi-select) mode
-        if (!isRangeSelectionActive()) {
-            // If a range selection isn't active, start one up
-            attemptSelect(mAdapter.getModelId(startPos));
-            setSelectionRangeBegin(startPos);
-        }
-        // Extend the range selection
-        mRanger.snapSelection(endPos);
+    /**
+     * Sets the end point for the current range selection, started by a call to
+     * {@link #startRangeSelection(int)}. This function should only be called when a range selection
+     * is active (see {@link #isRangeSelectionActive()}. Items in the range [anchor, end] will be
+     * selected.
+     *
+     * @param pos The new end position for the selection range.
+     */
+    void snapRangeSelection(int pos) {
+        checkNotNull(mRanger);
+        mRanger.snapSelection(pos);
         notifySelectionChanged();
     }
 
     /**
+     * Stops an in-progress range selection.
+     */
+    void endRangeSelection() {
+        mRanger = null;
+    }
+
+    /**
      * @return Whether or not there is a current range selection active.
      */
-    private boolean isRangeSelectionActive() {
+    boolean isRangeSelectionActive() {
         return mRanger != null;
     }
 
@@ -615,7 +644,7 @@
      * Object representing the current selection. Provides read only access
      * public access, and private write access.
      */
-    public static final class Selection {
+    public static final class Selection implements Parcelable {
 
         // This class tracks selected items by managing two sets: the saved selection, and the total
         // selection. Saved selections are those which have been completed by tapping an item or by
@@ -628,8 +657,9 @@
         // item A is tapped (and selected), then an in-progress band select covers A then uncovers
         // A, A should still be selected as it has been saved. To ensure this behavior, the saved
         // selection must be tracked separately.
-        private Set<String> mSavedSelection = new HashSet<>();
-        private Set<String> mTotalSelection = new HashSet<>();
+        private Set<String> mSelection = new HashSet<>();
+        private Set<String> mProvisionalSelection = new HashSet<>();
+        private String mDirectoryKey;
 
         @VisibleForTesting
         public Selection(String... ids) {
@@ -643,53 +673,70 @@
          * @return true if the position is currently selected.
          */
         public boolean contains(@Nullable String id) {
-            return mTotalSelection.contains(id);
+            return mSelection.contains(id) || mProvisionalSelection.contains(id);
         }
 
         /**
          * Returns an unordered array of selected positions.
          */
         public String[] getAll() {
-            return mTotalSelection.toArray(new String[0]);
+            return toList().toArray(new String[0]);
+        }
+
+        /**
+         * Returns an unordered array of selected positions (including any
+         * provisional selections current in effect).
+         */
+        private List<String> toList() {
+            ArrayList<String> selection = new ArrayList<String>(mSelection);
+            selection.addAll(mProvisionalSelection);
+            return selection;
         }
 
         /**
          * @return size of the selection.
          */
         public int size() {
-            return mTotalSelection.size();
+            return mSelection.size() + mProvisionalSelection.size();
         }
 
         /**
          * @return true if the selection is empty.
          */
         public boolean isEmpty() {
-            return mTotalSelection.isEmpty();
+            return mSelection.isEmpty() && mProvisionalSelection.isEmpty();
         }
 
         /**
          * Sets the provisional selection, which is a temporary selection that can be saved,
          * canceled, or adjusted at a later time. When a new provision selection is applied, the old
          * one (if it exists) is abandoned.
-         * @return Array with entry for each position added or removed. Entries which were added
-         *     contain a value of true, and entries which were removed contain a value of false.
+         * @return Map of ids added or removed. Added ids have a value of true, removed are false.
          */
         @VisibleForTesting
-        protected Map<String, Boolean> setProvisionalSelection(Set<String> provisionalSelection) {
+        protected Map<String, Boolean> setProvisionalSelection(Set<String> newSelection) {
             Map<String, Boolean> delta = new HashMap<>();
 
-            for (String id: mTotalSelection) {
+            for (String id: mProvisionalSelection) {
                 // Mark each item that used to be in the selection but is unsaved and not in the new
                 // provisional selection.
-                if (!provisionalSelection.contains(id) && !mSavedSelection.contains(id)) {
+                if (!newSelection.contains(id) && !mSelection.contains(id)) {
                     delta.put(id, false);
                 }
             }
 
-            for (String id: provisionalSelection) {
+            for (String id: mSelection) {
+                // Mark each item that used to be in the selection but is unsaved and not in the new
+                // provisional selection.
+                if (!newSelection.contains(id)) {
+                    delta.put(id, false);
+                }
+            }
+
+            for (String id: newSelection) {
                 // Mark each item that was not previously in the selection but is in the new
                 // provisional selection.
-                if (!mTotalSelection.contains(id)) {
+                if (!mSelection.contains(id) && !mProvisionalSelection.contains(id)) {
                     delta.put(id, true);
                 }
             }
@@ -700,9 +747,9 @@
             for (Map.Entry<String, Boolean> entry: delta.entrySet()) {
                 String id = entry.getKey();
                 if (entry.getValue()) {
-                    mTotalSelection.add(id);
+                    mProvisionalSelection.add(id);
                 } else {
-                    mTotalSelection.remove(id);
+                    mProvisionalSelection.remove(id);
                 }
             }
 
@@ -716,7 +763,8 @@
          */
         @VisibleForTesting
         protected void applyProvisionalSelection() {
-            mSavedSelection = new HashSet<>(mTotalSelection);
+            mSelection.addAll(mProvisionalSelection);
+            mProvisionalSelection.clear();
         }
 
         /**
@@ -725,15 +773,14 @@
          */
         @VisibleForTesting
         void cancelProvisionalSelection() {
-            mTotalSelection = new HashSet<>(mSavedSelection);
+            mProvisionalSelection.clear();
         }
 
         /** @hide */
         @VisibleForTesting
         boolean add(String id) {
-            if (!mTotalSelection.contains(id)) {
-                mTotalSelection.add(id);
-                mSavedSelection.add(id);
+            if (!mSelection.contains(id)) {
+                mSelection.add(id);
                 return true;
             }
             return false;
@@ -742,31 +789,29 @@
         /** @hide */
         @VisibleForTesting
         boolean remove(String id) {
-            if (mTotalSelection.contains(id)) {
-                mTotalSelection.remove(id);
-                mSavedSelection.remove(id);
+            if (mSelection.contains(id)) {
+                mSelection.remove(id);
                 return true;
             }
             return false;
         }
 
         public void clear() {
-            mSavedSelection.clear();
-            mTotalSelection.clear();
+            mSelection.clear();
         }
 
         /**
          * Trims this selection to be the intersection of itself with the set of given IDs.
          */
         public void intersect(Collection<String> ids) {
-            mSavedSelection.retainAll(ids);
-            mTotalSelection.retainAll(ids);
+            mSelection.retainAll(ids);
+            mProvisionalSelection.retainAll(ids);
         }
 
         @VisibleForTesting
         void copyFrom(Selection source) {
-            mSavedSelection = new HashSet<>(source.mSavedSelection);
-            mTotalSelection = new HashSet<>(source.mTotalSelection);
+            mSelection = new HashSet<>(source.mSelection);
+            mProvisionalSelection = new HashSet<>(source.mProvisionalSelection);
         }
 
         @Override
@@ -775,24 +820,19 @@
                 return "size=0, items=[]";
             }
 
-            StringBuilder buffer = new StringBuilder(mTotalSelection.size() * 28);
-            buffer.append("{size=")
-                    .append(mTotalSelection.size())
-                    .append(", ")
-                    .append("items=[");
-            for (Iterator<String> i = mTotalSelection.iterator(); i.hasNext(); ) {
-                buffer.append(i.next());
-                if (i.hasNext()) {
-                    buffer.append(", ");
-                }
-            }
-            buffer.append("]}");
+            StringBuilder buffer = new StringBuilder(size() * 28);
+            buffer.append("Selection{")
+                .append("applied{size=" + mSelection.size())
+                .append(", entries=" + mSelection)
+                .append("}, provisional{size=" + mProvisionalSelection.size())
+                .append(", entries=" + mProvisionalSelection)
+                .append("}}");
             return buffer.toString();
         }
 
         @Override
         public int hashCode() {
-            return mSavedSelection.hashCode() ^ mTotalSelection.hashCode();
+            return mSelection.hashCode() ^ mProvisionalSelection.hashCode();
         }
 
         @Override
@@ -805,8 +845,38 @@
               return false;
           }
 
-          return mSavedSelection.equals(((Selection) that).mSavedSelection) &&
-                  mTotalSelection.equals(((Selection) that).mTotalSelection);
+          return mSelection.equals(((Selection) that).mSelection) &&
+                  mProvisionalSelection.equals(((Selection) that).mProvisionalSelection);
+        }
+
+        /**
+         * Sets the state key for this selection, which allows us to match selections
+         * to particular states (of DirectoryFragment). Basically this lets us avoid
+         * loading a persisted selection in the wrong directory.
+         */
+        public void setDirectoryKey(String key) {
+            mDirectoryKey = key;
+        }
+
+        /**
+         * Sets the state key for this selection, which allows us to match selections
+         * to particular states (of DirectoryFragment). Basically this lets us avoid
+         * loading a persisted selection in the wrong directory.
+         */
+        public boolean hasDirectoryKey(String key) {
+            return key.equals(mDirectoryKey);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(mDirectoryKey);
+            dest.writeList(new ArrayList<>(mSelection));
+            // We don't include provisional selection since it is
+            // typically coupled to some other runtime state (like a band).
         }
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
index 0bb682e..7394c12 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -36,6 +36,7 @@
 import android.support.design.widget.Snackbar;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.EditText;
@@ -47,6 +48,7 @@
 import com.android.documentsui.R;
 import com.android.documentsui.Snackbars;
 import com.android.documentsui.model.DocumentInfo;
+
 /**
  * Dialog to rename file or directory.
  */
@@ -68,8 +70,7 @@
         View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
 
         final EditText editText = (EditText) view.findViewById(android.R.id.text1);
-        editText.setText(mDocument.displayName);
-
+        fillWithFileName(editText, mDocument.displayName);
         builder.setTitle(R.string.menu_rename);
         builder.setView(view);
 
@@ -91,9 +92,9 @@
                     @Override
                     public boolean onEditorAction(
                             TextView view, int actionId, @Nullable KeyEvent event) {
-                        if (event != null
+                        if ((actionId == EditorInfo.IME_ACTION_DONE) || (event != null
                                 && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
-                                && event.hasNoModifiers()) {
+                                && event.hasNoModifiers())) {
                             renameDocuments(editText.getText().toString());
                             dialog.dismiss();
                             return true;
@@ -105,10 +106,39 @@
         return dialog;
     }
 
+    /**
+     * Validates if string is a proper document name.
+     * Checks if string is not empty. More rules might be added later.
+     * @param docName string representing document name
+     * @returns true if string is a valid name.
+     **/
+    private boolean isValidDocumentName(String docName) {
+        return !docName.isEmpty();
+    }
+
+    /**
+     * Fills text field with the file name and selects the name without extension.
+     *
+     * @param editText text field to be filled
+     * @param name full name of the file
+     */
+    private void fillWithFileName(EditText editText, String name) {
+        editText.setText(name);
+        int separatorIndex = name.indexOf(".");
+        editText.setSelection(0, separatorIndex == -1 ? name.length() : separatorIndex);
+    }
+
     private void renameDocuments(String newDisplayName) {
         BaseActivity activity = (BaseActivity) getActivity();
 
-        new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
+        if (isValidDocumentName(newDisplayName)) {
+            new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
+        } else {
+            Log.w(TAG, "Failed to rename file - invalid name:" + newDisplayName);
+            Snackbars.makeSnackbar(getActivity(), R.string.rename_error,
+                    Snackbar.LENGTH_SHORT).show();
+        }
+
     }
 
     private class RenameDocumentsTask extends AsyncTask<DocumentInfo, Void, DocumentInfo> {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 4b5499a..1c696ad 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -39,6 +39,7 @@
 import java.io.IOException;
 import java.net.ProtocolException;
 import java.text.Collator;
+import java.util.Objects;
 
 /**
  * Representation of a {@link Document}.
@@ -263,16 +264,23 @@
         return derivedUri.hashCode() + mimeType.hashCode();
     }
 
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (!(other instanceof DocumentInfo)) {
+    public boolean equals(Object o) {
+        if (o == null) {
             return false;
         }
 
-        DocumentInfo that = (DocumentInfo) other;
-        // Uri + mime type should be totally unique.
-        return derivedUri.equals(that.derivedUri) && mimeType.equals(that.mimeType);
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof DocumentInfo) {
+            DocumentInfo other = (DocumentInfo) o;
+            // Uri + mime type should be totally unique.
+            return Objects.equals(derivedUri, other.derivedUri)
+                    && Objects.equals(mimeType, other.mimeType);
+        }
+
+        return false;
     }
 
     public static String getCursorString(Cursor cursor, String columnName) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index 3f14a55..f4a97be 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -171,7 +171,7 @@
 
         // TODO: remove these special case icons
         if (isHome()) {
-            derivedIcon = R.drawable.ic_root_home;
+            derivedIcon = R.drawable.ic_root_documents;
             derivedType = TYPE_LOCAL;
         } else if (isExternalStorage()) {
             derivedIcon = R.drawable.ic_root_smartphone;
@@ -276,12 +276,21 @@
 
     @Override
     public boolean equals(Object o) {
-        if (o instanceof RootInfo) {
-            final RootInfo root = (RootInfo) o;
-            return Objects.equals(authority, root.authority) && Objects.equals(rootId, root.rootId);
-        } else {
+        if (o == null) {
             return false;
         }
+
+        if (this == o) {
+            return true;
+        }
+
+        if (o instanceof RootInfo) {
+            RootInfo other = (RootInfo) o;
+            return Objects.equals(authority, other.authority)
+                    && Objects.equals(rootId, other.rootId);
+        }
+
+        return false;
     }
 
     @Override
diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
index 3a025c2..05a3f11 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/services/FileOperationService.java
@@ -71,11 +71,6 @@
     // such case, this needs to be replaced with pairs of parent and child.
     public static final String EXTRA_SRC_PARENT = "com.android.documentsui.SRC_PARENT";
 
-    public static final int OPERATION_UNKNOWN = -1;
-    public static final int OPERATION_COPY = 1;
-    public static final int OPERATION_MOVE = 2;
-    public static final int OPERATION_DELETE = 3;
-
     @IntDef(flag = true, value = {
             OPERATION_UNKNOWN,
             OPERATION_COPY,
@@ -84,6 +79,10 @@
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface OpType {}
+    public static final int OPERATION_UNKNOWN = -1;
+    public static final int OPERATION_COPY = 1;
+    public static final int OPERATION_MOVE = 2;
+    public static final int OPERATION_DELETE = 3;
 
     // TODO: Move it to a shared file when more operations are implemented.
     public static final int FAILURE_COPY = 1;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java
new file mode 100644
index 0000000..34f1120
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/ActivityTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.provider.DocumentsContract.Document;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.Until;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.MotionEvent;
+
+import com.android.documentsui.model.RootInfo;
+
+/**
+ * Provides basic test environment for UI tests:
+ * - Launches activity
+ * - Creates and gives access to test root directories and test files
+ * - Cleans up the test environment
+ */
+public abstract class ActivityTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
+
+    static final int TIMEOUT = 5000;
+
+    // Testing files. For custom ones, override initTestFiles().
+    public static final String dirName1 = "Dir1";
+    public static final String fileName1 = "file1.log";
+    public static final String fileName2 = "file12.png";
+    public static final String fileName3 = "anotherFile0.log";
+    public static final String fileName4 = "poodles.text";
+    public static final String fileNameNoRename = "NO_RENAMEfile.txt";
+
+    public UiBot bot;
+    public UiDevice device;
+    public Context context;
+
+    public RootInfo rootDir0;
+    public RootInfo rootDir1;
+
+    ContentResolver mResolver;
+    DocumentsProviderHelper mDocsHelper;
+    ContentProviderClient mClient;
+
+    public ActivityTest(Class<T> activityClass) {
+        super(activityClass);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        device = UiDevice.getInstance(getInstrumentation());
+        // NOTE: Must be the "target" context, else security checks in content provider will fail.
+        context = getInstrumentation().getTargetContext();
+        bot = new UiBot(device, context, TIMEOUT);
+
+        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
+        bot.revealLauncher();
+
+        mResolver = context.getContentResolver();
+        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
+        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
+
+        rootDir0 = mDocsHelper.getRoot(ROOT_0_ID);
+        rootDir1 = mDocsHelper.getRoot(ROOT_1_ID);
+
+        launchActivity();
+
+        bot.revealApp();
+        resetStorage();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mClient.release();
+        super.tearDown();
+    }
+
+    void launchActivity() {
+        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
+                UiBot.TARGET_PKG);
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+        setActivityIntent(intent);
+        getActivity();  // Launch the activity.
+    }
+
+    void resetStorage() throws RemoteException {
+        mClient.call("clear", null, null);
+        device.waitForIdle();
+    }
+
+    void initTestFiles() throws RemoteException {
+        mDocsHelper.createFolder(rootDir0, dirName1);
+        mDocsHelper.createDocument(rootDir0, "text/plain", fileName1);
+        mDocsHelper.createDocument(rootDir0, "image/png", fileName2);
+        mDocsHelper.createDocumentWithFlags(rootDir0.documentId, "text/plain", fileNameNoRename,
+                Document.FLAG_SUPPORTS_WRITE);
+
+        mDocsHelper.createDocument(rootDir1, "text/plain", fileName3);
+        mDocsHelper.createDocument(rootDir1, "text/plain", fileName4);
+    }
+
+    void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException {
+        bot.assertDocumentsCount(ROOT_0_ID, 4);
+        bot.assertHasDocuments(fileName1, fileName2, dirName1, fileNameNoRename);
+    }
+
+    void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException {
+        bot.assertDocumentsCount(ROOT_1_ID, 2);
+        bot.assertHasDocuments(fileName3, fileName4);
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
index 5df4dca..af478ea 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java
@@ -92,7 +92,8 @@
             Uri uri = DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
             return uri;
         } catch (RemoteException e) {
-            throw new RuntimeException("Couldn't create document: " + name + " with mimetype " + mimeType, e);
+            throw new RuntimeException("Couldn't create document: " + name + " with mimetype "
+                    + mimeType, e);
         }
     }
 
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java
index 243c357..c51f927 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java
@@ -16,144 +16,86 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
 
-import android.app.Instrumentation;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
 import android.content.Intent;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
 import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.Until;
-import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.documentsui.model.RootInfo;
 
 @LargeTest
-public class DownloadsActivityUiTest extends ActivityInstrumentationTestCase2<DownloadsActivity> {
-
-    private static final int TIMEOUT = 5000;
-    private static final String TAG = "DownloadsActivityUiTest";
-    private static final String TARGET_PKG = "com.android.documentsui";
-    private static final String LAUNCHER_PKG = "com.android.launcher";
-
-    private UiBot mBot;
-    private UiDevice mDevice;
-    private Context mContext;
-    private ContentResolver mResolver;
-    private DocumentsProviderHelper mDocsHelper;
-    private ContentProviderClient mClient;
-    private RootInfo mRoot;
+public class DownloadsActivityUiTest extends ActivityTest<DownloadsActivity> {
 
     public DownloadsActivityUiTest() {
         super(DownloadsActivity.class);
     }
 
-    public void setUp() throws Exception {
-        // Initialize UiDevice instance.
-        Instrumentation instrumentation = getInstrumentation();
-
-        mDevice = UiDevice.getInstance(instrumentation);
-
-        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
-
-        // Start from the home screen.
-        mDevice.pressHome();
-        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
-
-        // NOTE: Must be the "target" context, else security checks in content provider will fail.
-        mContext = instrumentation.getTargetContext();
-        mResolver = mContext.getContentResolver();
-
-        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
-        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
-
-        mRoot = mDocsHelper.getRoot(ROOT_0_ID);
-
-        // Open the Downloads activity on our stub provider root.
-        Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT);
-        intent.setDataAndType(mRoot.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
+    @Override
+    void launchActivity() {
+        final Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT);
+        intent.setDataAndType(rootDir0.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
         setActivityIntent(intent);
-        getActivity();  // Start the activity.
-
-        // Wait for the app to appear.
-        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
-        mDevice.waitForIdle();
-
-        mBot = new UiBot(mDevice, mContext, TIMEOUT);
-
-        resetStorage();  // Just in case a test failed and tearDown didn't happen.
+        getActivity();  // Launch the activity.
     }
 
     @Override
-    protected void tearDown() throws Exception {
-        Log.d(TAG, "Resetting storage from setUp");
-        resetStorage();
-        mClient.release();
-
-        super.tearDown();
-    }
-
-    private void resetStorage() throws RemoteException {
-        mClient.call("clear", null, null);
-        // TODO: Would be nice to have an event to wait on here.
-        mDevice.waitForIdle();
-    }
-
-    private void initTestFiles() throws RemoteException {
-        mDocsHelper.createDocument(mRoot, "text/plain", "file0.log");
-        mDocsHelper.createDocument(mRoot, "image/png", "file1.png");
-        mDocsHelper.createDocument(mRoot, "text/csv", "file2.csv");
+    void initTestFiles() throws RemoteException {
+        mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log");
+        mDocsHelper.createDocument(rootDir0, "image/png", "file1.png");
+        mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv");
     }
 
     public void testWindowTitle() throws Exception {
         initTestFiles();
 
-        mBot.assertWindowTitle(ROOT_0_ID);
+        bot.assertWindowTitle(ROOT_0_ID);
     }
 
     public void testFilesListed() throws Exception {
         initTestFiles();
 
-        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
+        bot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
     }
 
     public void testFilesList_LiveUpdate() throws Exception {
         initTestFiles();
 
-        mDocsHelper.createDocument(mRoot, "yummers/sandwich", "Ham & Cheese.sandwich");
-        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
+        mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
+
+        bot.waitForDocument("Ham & Cheese.sandwich");
+        bot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
     }
 
     public void testDeleteDocument() throws Exception {
         initTestFiles();
 
-        mBot.clickDocument("file1.png");
-        mDevice.waitForIdle();
-        mBot.menuDelete().click();
+        bot.clickDocument("file1.png");
+        device.waitForIdle();
+        bot.menuDelete().click();
 
-        mBot.waitForDeleteSnackbar();
-        assertFalse(mBot.hasDocuments("file1.png"));
+        bot.waitForDeleteSnackbar();
+        assertFalse(bot.hasDocuments("file1.png"));
 
-        mBot.waitForDeleteSnackbarGone();
-        assertFalse(mBot.hasDocuments("file1.png"));
+        bot.waitForDeleteSnackbarGone();
+        assertFalse(bot.hasDocuments("file1.png"));
     }
 
     public void testSupportsShare() throws Exception {
         initTestFiles();
 
-        mBot.clickDocument("file1.png");
-        mDevice.waitForIdle();
-        assertNotNull(mBot.menuShare());
+        bot.clickDocument("file1.png");
+        device.waitForIdle();
+        assertNotNull(bot.menuShare());
+    }
+
+    public void testClosesOnBack() throws Exception {
+        DownloadsActivity activity = getActivity();
+        device.pressBack();
+        device.wait(Until.gone(By.text(ROOT_0_ID)), TIMEOUT);  // wait for the window to go away
+        assertTrue(activity.isDestroyed());
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
index 868dbbb..95515db 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -16,123 +16,43 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
 import static com.android.documentsui.StubProvider.ROOT_1_ID;
 
-import android.app.Instrumentation;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
 import android.os.RemoteException;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.Until;
-import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.documentsui.model.RootInfo;
+import android.view.KeyEvent;
 
 @LargeTest
-public class FilesActivityUiTest extends ActivityInstrumentationTestCase2<FilesActivity> {
-
-    private static final int TIMEOUT = 5000;
-    private static final String TAG = "FilesActivityUiTest";
-    private static final String TARGET_PKG = "com.android.documentsui";
-    private static final String LAUNCHER_PKG = "com.android.launcher";
-
-    private UiBot mBot;
-    private UiDevice mDevice;
-    private Context mContext;
-    private ContentResolver mResolver;
-    private DocumentsProviderHelper mDocsHelper;
-    private ContentProviderClient mClient;
-    private RootInfo mRoot_0;
-    private RootInfo mRoot_1;
+public class FilesActivityUiTest extends ActivityTest<FilesActivity> {
 
     public FilesActivityUiTest() {
         super(FilesActivity.class);
     }
 
-    public void setUp() throws Exception {
-        // Initialize UiDevice instance.
-        Instrumentation instrumentation = getInstrumentation();
-
-        mDevice = UiDevice.getInstance(instrumentation);
-
-        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
-
-        // Start from the home screen.
-        mDevice.pressHome();
-        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
-
-        // NOTE: Must be the "target" context, else security checks in content provider will fail.
-        mContext = instrumentation.getTargetContext();
-        mResolver = mContext.getContentResolver();
-
-        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
-        assertNotNull("Failed to acquire ContentProviderClient.", mClient);
-        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
-
-        // Launch app.
-        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG);
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        setActivityIntent(intent);
-        getActivity();  // Start the activity.
-
-        // Wait for the app to appear.
-        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
-        mDevice.waitForIdle();
-
-        mBot = new UiBot(mDevice, mContext, TIMEOUT);
-
-        resetStorage();  // Just incase a test failed and tearDown didn't happen.
-    }
-
     @Override
-    protected void tearDown() throws Exception {
-        Log.d(TAG, "Resetting storage from setUp");
-        resetStorage();
-        mClient.release();
+    public void initTestFiles() throws RemoteException {
+        mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log");
+        mDocsHelper.createDocument(rootDir0, "image/png", "file1.png");
+        mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv");
 
-        super.tearDown();
-    }
-
-    private void resetStorage() throws RemoteException {
-        mClient.call("clear", null, null);
-        // TODO: Would be nice to have an event to wait on here.
-        mDevice.waitForIdle();
-    }
-
-    private void initTestFiles() throws RemoteException {
-        mRoot_0 = mDocsHelper.getRoot(ROOT_0_ID);
-        mRoot_1 = mDocsHelper.getRoot(ROOT_1_ID);
-
-        mDocsHelper.createDocument(mRoot_0, "text/plain", "file0.log");
-        mDocsHelper.createDocument(mRoot_0, "image/png", "file1.png");
-        mDocsHelper.createDocument(mRoot_0, "text/csv", "file2.csv");
-
-        mDocsHelper.createDocument(mRoot_1, "text/plain", "anotherFile0.log");
-        mDocsHelper.createDocument(mRoot_1, "text/plain", "poodles.text");
+        mDocsHelper.createDocument(rootDir1, "text/plain", "anotherFile0.log");
+        mDocsHelper.createDocument(rootDir1, "text/plain", "poodles.text");
     }
 
     public void testRootsListed() throws Exception {
         initTestFiles();
 
-        mBot.openRoot(ROOT_0_ID);
+        bot.openRoot(ROOT_0_ID);
 
         // Should also have Drive, but that requires pre-configuration of devices
         // We omit for now.
-        mBot.assertHasRoots(
+        bot.assertHasRoots(
                 "Images",
                 "Videos",
                 "Audio",
                 "Downloads",
-                "Home",
+                "Documents",
                 ROOT_0_ID,
                 ROOT_1_ID);
     }
@@ -140,60 +60,93 @@
     public void testFilesListed() throws Exception {
         initTestFiles();
 
-        mBot.openRoot(ROOT_0_ID);
-        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
+        bot.openRoot(ROOT_0_ID);
+        bot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
     }
 
-    public void testLoadsHomeByDefault() throws Exception {
+    public void testLoadsHomeDirectoryByDefault() throws Exception {
         initTestFiles();
 
-        mDevice.waitForIdle();
-        mBot.assertWindowTitle("Home");
+        device.waitForIdle();
+        bot.assertWindowTitle("Documents");
     }
 
     public void testRootClickSetsWindowTitle() throws Exception {
         initTestFiles();
 
-        mBot.openRoot("Downloads");
-        mBot.assertWindowTitle("Downloads");
+        bot.openRoot("Downloads");
+        bot.assertWindowTitle("Downloads");
     }
 
     public void testFilesList_LiveUpdate() throws Exception {
         initTestFiles();
 
-        mBot.openRoot(ROOT_0_ID);
-        mDocsHelper.createDocument(mRoot_0, "yummers/sandwich", "Ham & Cheese.sandwich");
+        bot.openRoot(ROOT_0_ID);
+        mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich");
 
-        mDevice.waitForIdle();
-        mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
+        bot.waitForDocument("Ham & Cheese.sandwich");
+        bot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
     }
 
     public void testDeleteDocument() throws Exception {
         initTestFiles();
 
-        mBot.openRoot(ROOT_0_ID);
+        bot.openRoot(ROOT_0_ID);
 
-        mBot.clickDocument("file1.png");
-        mDevice.waitForIdle();
-        mBot.menuDelete().click();
+        bot.clickDocument("file1.png");
+        device.waitForIdle();
+        bot.menuDelete().click();
 
-        mBot.waitForDeleteSnackbar();
-        assertFalse(mBot.hasDocuments("file1.png"));
+        bot.waitForDeleteSnackbar();
+        assertFalse(bot.hasDocuments("file1.png"));
 
-        mBot.waitForDeleteSnackbarGone();
-        assertFalse(mBot.hasDocuments("file1.png"));
+        bot.waitForDeleteSnackbarGone();
+        assertFalse(bot.hasDocuments("file1.png"));
 
         // Now delete from another root.
-        mBot.openRoot(ROOT_1_ID);
+        bot.openRoot(ROOT_1_ID);
 
-        mBot.clickDocument("poodles.text");
-        mDevice.waitForIdle();
-        mBot.menuDelete().click();
+        bot.clickDocument("poodles.text");
+        device.waitForIdle();
+        bot.menuDelete().click();
 
-        mBot.waitForDeleteSnackbar();
-        assertFalse(mBot.hasDocuments("poodles.text"));
+        bot.waitForDeleteSnackbar();
+        assertFalse(bot.hasDocuments("poodles.text"));
 
-        mBot.waitForDeleteSnackbarGone();
-        assertFalse(mBot.hasDocuments("poodles.text"));
+        bot.waitForDeleteSnackbarGone();
+        assertFalse(bot.hasDocuments("poodles.text"));
+    }
+
+    // Tests that pressing tab switches focus between the roots and directory listings.
+    public void testKeyboard_tab() throws Exception {
+        bot.pressKey(KeyEvent.KEYCODE_TAB);
+        bot.assertHasFocus("com.android.documentsui:id/roots_list");
+        bot.pressKey(KeyEvent.KEYCODE_TAB);
+        bot.assertHasFocus("com.android.documentsui:id/dir_list");
+    }
+
+    // Tests that arrow keys do not switch focus away from the dir list.
+    public void testKeyboard_arrowsDirList() throws Exception {
+        for (int i = 0; i < 10; i++) {
+            bot.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
+            bot.assertHasFocus("com.android.documentsui:id/dir_list");
+        }
+        for (int i = 0; i < 10; i++) {
+            bot.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
+            bot.assertHasFocus("com.android.documentsui:id/dir_list");
+        }
+    }
+
+    // Tests that arrow keys do not switch focus away from the roots list.
+    public void testKeyboard_arrowsRootsList() throws Exception {
+        bot.pressKey(KeyEvent.KEYCODE_TAB);
+        for (int i = 0; i < 10; i++) {
+            bot.pressKey(KeyEvent.KEYCODE_DPAD_RIGHT);
+            bot.assertHasFocus("com.android.documentsui:id/roots_list");
+        }
+        for (int i = 0; i < 10; i++) {
+            bot.pressKey(KeyEvent.KEYCODE_DPAD_LEFT);
+            bot.assertHasFocus("com.android.documentsui:id/roots_list");
+        }
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
index 5c6254f..770bc2c 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RenameDocumentUiTest.java
@@ -17,150 +17,143 @@
 package com.android.documentsui;
 
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
-import static com.android.documentsui.UiTestEnvironment.TIMEOUT;
 
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
 @LargeTest
-public class RenameDocumentUiTest extends InstrumentationTestCase {
+public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {
 
     private static final String TAG = "RenamDocumentUiTest";
 
     private final String newName = "kitties.log";
 
-    private UiTestEnvironment mHelper;
+    public RenameDocumentUiTest() {
+        super(FilesActivity.class);
+    }
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mHelper = new UiTestEnvironment(getInstrumentation());
-        mHelper.launch();
-        mHelper.initTestFiles();
-        mHelper.bot().openRoot(ROOT_0_ID);
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
     }
 
     public void testRenameEnabled_SingleSelection() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().assertMenuEnabled(R.string.menu_rename, true);
+        bot.selectDocument(fileName1);
+        bot.openOverflowMenu();
+        bot.assertMenuEnabled(R.string.menu_rename, true);
 
         // Dismiss more options window
-        mHelper.device().pressBack();
+        device.pressBack();
     }
 
     public void testNoRenameSupport_SingleSelection() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileNameNoRename);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().assertMenuEnabled(R.string.menu_rename, false);
+        bot.selectDocument(fileNameNoRename);
+        bot.openOverflowMenu();
+        bot.assertMenuEnabled(R.string.menu_rename, false);
 
         // Dismiss more options window
-        mHelper.device().pressBack();
+        device.pressBack();
     }
 
     public void testOneHasRenameSupport_MultipleSelection() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().selectDocument(UiTestEnvironment.fileNameNoRename);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().assertMenuEnabled(R.string.menu_rename, false);
+        bot.selectDocument(fileName1);
+        bot.selectDocument(fileNameNoRename);
+        bot.openOverflowMenu();
+        bot.assertMenuEnabled(R.string.menu_rename, false);
 
         // Dismiss more options window
-        mHelper.device().pressBack();
+        device.pressBack();
     }
 
     public void testRenameDisabled_MultipleSelection() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName2);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().assertMenuEnabled(R.string.menu_rename, false);
+        bot.selectDocument(fileName1);
+        bot.selectDocument(fileName2);
+        bot.openOverflowMenu();
+        bot.assertMenuEnabled(R.string.menu_rename, false);
 
         // Dismiss more options window
-        mHelper.device().pressBack();
+        device.pressBack();
     }
 
     public void testRenameFile_OkButton() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().openDialog(R.string.menu_rename);
-        mHelper.bot().setDialogText(newName);
-        mHelper.bot().dismissKeyboardIfPresent();
+        bot.selectDocument(fileName1);
+        bot.openOverflowMenu();
+        bot.openDialog(R.string.menu_rename);
+        bot.setDialogText(newName);
 
-        mHelper.device().waitForIdle(TIMEOUT);
-        mHelper.bot().findRenameDialogOkButton().click();
-        mHelper.device().waitForIdle(TIMEOUT);
+        device.waitForIdle(TIMEOUT);
+        bot.findRenameDialogOkButton().click();
+        device.waitForIdle(TIMEOUT);
 
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName1, false);
-        mHelper.bot().assertDocument(newName, true);
-        mHelper.bot().assertDocumentsCount(mHelper.getDocumentsCountDir0());
+        bot.assertDocument(fileName1, false);
+        bot.assertDocument(newName, true);
+        bot.assertDocumentsCount(4);
     }
 
     public void testRenameFile_Enter() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().openDialog(R.string.menu_rename);
-        mHelper.bot().setDialogText(newName);
+        bot.selectDocument(fileName1);
+        bot.openOverflowMenu();
+        bot.openDialog(R.string.menu_rename);
+        bot.setDialogText(newName);
 
         pressEnter();
 
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName1, false);
-        mHelper.bot().assertDocument(newName, true);
-        mHelper.bot().assertDocumentsCount(mHelper.getDocumentsCountDir0());
+        bot.assertDocument(fileName1, false);
+        bot.assertDocument(newName, true);
+        bot.assertDocumentsCount(4);
     }
 
     public void testRenameFile_Cancel() throws Exception {
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().openDialog(R.string.menu_rename);
-        mHelper.bot().setDialogText(newName);
-        mHelper.bot().dismissKeyboardIfPresent();
+        bot.selectDocument(fileName1);
+        bot.openOverflowMenu();
+        bot.openDialog(R.string.menu_rename);
+        bot.setDialogText(newName);
 
-        mHelper.device().waitForIdle(TIMEOUT);
-        mHelper.bot().findRenameDialogCancelButton().click();
-        mHelper.device().waitForIdle(TIMEOUT);
+        device.waitForIdle(TIMEOUT);
+        bot.findRenameDialogCancelButton().click();
+        device.waitForIdle(TIMEOUT);
 
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName1, true);
-        mHelper.bot().assertDocument(newName, false);
-        mHelper.bot().assertDocumentsCount(mHelper.getDocumentsCountDir0());
+        bot.assertDocument(fileName1, true);
+        bot.assertDocument(newName, false);
+        bot.assertDocumentsCount(4);
     }
 
     public void testRenameDir() throws Exception {
         String oldName = "Dir1";
         String newName = "Dir123";
 
-        mHelper.bot().selectDocument(oldName);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().openDialog(R.string.menu_rename);
-        mHelper.bot().setDialogText(newName);
+        bot.selectDocument(oldName);
+        bot.openOverflowMenu();
+        bot.openDialog(R.string.menu_rename);
+        bot.setDialogText(newName);
 
         pressEnter();
 
-        mHelper.bot().assertDocument(oldName, false);
-        mHelper.bot().assertDocument(newName, true);
-        mHelper.bot().assertDocumentsCount(mHelper.getDocumentsCountDir0());
+        bot.assertDocument(oldName, false);
+        bot.assertDocument(newName, true);
+        bot.assertDocumentsCount(4);
     }
 
     public void testRename_NameExists() throws Exception {
         // Check that document with the new name exists
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName2, true);
-        mHelper.bot().selectDocument(UiTestEnvironment.fileName1);
-        mHelper.bot().openOverflowMenu();
-        mHelper.bot().openDialog(R.string.menu_rename);
-        mHelper.bot().setDialogText(UiTestEnvironment.fileName2);
+        bot.assertDocument(fileName2, true);
+        bot.selectDocument(fileName1);
+        bot.openOverflowMenu();
+        bot.openDialog(R.string.menu_rename);
+        bot.setDialogText(fileName2);
 
         pressEnter();
 
-        mHelper.bot().assertSnackbar(R.string.rename_error);
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName1, true);
-        mHelper.bot().assertDocument(UiTestEnvironment.fileName2, true);
-        mHelper.bot().assertDocumentsCount(mHelper.getDocumentsCountDir0());
+        bot.assertSnackbar(R.string.rename_error);
+        bot.assertDocument(fileName1, true);
+        bot.assertDocument(fileName2, true);
+        bot.assertDocumentsCount(4);
     }
 
     private void pressEnter() {
-        mHelper.device().waitForIdle(TIMEOUT);
-        mHelper.device().pressEnter();
-        mHelper.device().waitForIdle(TIMEOUT);
+        device.waitForIdle(TIMEOUT);
+        device.pressEnter();
+        device.waitForIdle(TIMEOUT);
     }
-
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootUiTest.java
new file mode 100644
index 0000000..1d1d3b5
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootUiTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.view.MotionEvent;
+
+@LargeTest
+public class RootUiTest extends ActivityTest<FilesActivity> {
+
+    private static final String TAG = "RootUiTest";
+
+    public RootUiTest() {
+        super(FilesActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+    }
+
+    public void testRootTapped_GoToRootFromChildDir() throws Exception {
+        bot.openDocument(dirName1);
+        bot.assertWindowTitle(dirName1);
+        bot.openRoot(ROOT_0_ID);
+        bot.assertWindowTitle(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
index 042ec85..b8d8795 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
@@ -19,143 +19,135 @@
 import static com.android.documentsui.StubProvider.ROOT_0_ID;
 import static com.android.documentsui.StubProvider.ROOT_1_ID;
 
-import android.support.test.uiautomator.UiObject;
-import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
 @LargeTest
-public class SearchViewUiTest extends InstrumentationTestCase {
+public class SearchViewUiTest extends ActivityTest<FilesActivity> {
 
     private static final String TAG = "SearchViewUiTest";
 
-    private UiTestEnvironment mEnv;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mEnv = new UiTestEnvironment(getInstrumentation());
-        mEnv.launch();
-
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mEnv.device().pressBack();
-        super.tearDown();
+    public SearchViewUiTest() {
+        super(FilesActivity.class);
     }
 
     public void testSearchView_ExpandsOnClick() throws Exception {
-        mEnv.bot().openSearchView();
-        mEnv.bot().assertSearchTextFiledAndIcon(true, false);
+        bot.openSearchView();
+        bot.assertSearchTextFiledAndIcon(true, false);
     }
 
     public void testSearchView_CollapsesOnBack() throws Exception {
-        mEnv.bot().openSearchView();
+        bot.openSearchView();
 
-        mEnv.device().pressBack();
+        device.pressBack();
 
-        mEnv.bot().assertSearchTextFiledAndIcon(false, true);
+        bot.assertSearchTextFiledAndIcon(false, true);
     }
 
     public void testSearchView_ClearsTextOnBack() throws Exception {
         String query = "file2";
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
+        bot.openSearchView();
+        bot.setSearchQuery(query);
 
-        mEnv.device().pressBack();
+        device.pressBack();
 
-        mEnv.bot().assertSearchTextFiledAndIcon(false, true);
+        bot.assertSearchTextFiledAndIcon(false, true);
     }
 
     public void testSearch_ResultsFound() throws Exception {
-        mEnv.initTestFiles();
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
 
         String query = "file1";
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
-        mEnv.bot().assertSearchTextField(true, query);
+        bot.openSearchView();
+        bot.setSearchQuery(query);
+        bot.assertSearchTextField(true, query);
 
-        mEnv.device().pressEnter();
+        device.pressEnter();
 
-        mEnv.bot().assertDocumentsCountOnList(true, 2);
-        mEnv.bot().assertHasDocuments(UiTestEnvironment.fileName1, UiTestEnvironment.fileName2);
-        mEnv.bot().assertSearchTextField(false, query);
+        bot.assertDocumentsCountOnList(true, 2);
+        bot.assertHasDocuments(fileName1, fileName2);
+
+        bot.assertSearchTextField(false, query);
     }
 
     public void testSearchResultsFound_ClearsOnBack() throws Exception {
-        mEnv.initTestFiles();
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
 
-        String query = UiTestEnvironment.fileName1;
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
+        String query = fileName1;
+        bot.openSearchView();
+        bot.setSearchQuery(query);
 
-        mEnv.device().pressEnter();
-        mEnv.device().pressBack();
-        mEnv.assertDefaultContentOfTestDir0();
+        device.pressEnter();
+        device.pressBack();
+
+        assertDefaultContentOfTestDir0();
     }
 
     public void testSearch_NoResults() throws Exception {
-        mEnv.initTestFiles();
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
 
         String query = "chocolate";
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
+        bot.openSearchView();
+        bot.setSearchQuery(query);
 
-        mEnv.device().pressEnter();
+        device.pressEnter();
 
-        mEnv.bot().assertDocumentsCountOnList(false, 0);
+        bot.assertDocumentsCountOnList(false, 0);
 
-        String msg = String.valueOf(mEnv.context().getString(R.string.no_results));
-        mEnv.bot().assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
-        mEnv.bot().assertSearchTextField(false, query);
+        device.waitForIdle();
+        String msg = String.valueOf(context.getString(R.string.no_results));
+        bot.assertMessageTextView(String.format(msg, "TEST_ROOT_0"));
+
+        bot.assertSearchTextField(false, query);
     }
 
     public void testSearchNoResults_ClearsOnBack() throws Exception {
-        mEnv.initTestFiles();
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
 
         String query = "chocolate";
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
+        bot.openSearchView();
+        bot.setSearchQuery(query);
 
-        mEnv.device().pressEnter();
-        mEnv.device().pressBack();
-        mEnv.assertDefaultContentOfTestDir0();
+        device.pressEnter();
+        device.pressBack();
+
+        device.waitForIdle();
+        assertDefaultContentOfTestDir0();
     }
 
     public void testSearchResultsFound_ClearsOnDirectoryChange() throws Exception {
-        mEnv.initTestFiles();
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        initTestFiles();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
 
-        String query = UiTestEnvironment.fileName1;
-        mEnv.bot().openSearchView();
-        mEnv.bot().setSearchQuery(query);
+        String query = fileName1;
+        bot.openSearchView();
+        bot.setSearchQuery(query);
 
-        mEnv.device().pressEnter();
+        device.pressEnter();
 
-        mEnv.bot().openRoot(ROOT_1_ID);
-        mEnv.assertDefaultContentOfTestDir1();
+        bot.openRoot(ROOT_1_ID);
+        assertDefaultContentOfTestDir1();
 
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.assertDefaultContentOfTestDir0();
+        bot.openRoot(ROOT_0_ID);
+        assertDefaultContentOfTestDir0();
     }
 
     public void testSearchIconVisible_RootWithSearchSupport() throws Exception {
-        mEnv.bot().openRoot(ROOT_0_ID);
-        mEnv.bot().assertSearchTextFiledAndIcon(false, true);
+        bot.openRoot(ROOT_0_ID);
+        bot.assertSearchTextFiledAndIcon(false, true);
     }
 
     public void testSearchIconHidden_RootNoSearchSupport() throws Exception {
-        mEnv.bot().openRoot(ROOT_1_ID);
-        mEnv.bot().assertSearchTextFiledAndIcon(false, false);
+        bot.openRoot(ROOT_1_ID);
+        bot.assertSearchTextFiledAndIcon(false, false);
     }
 
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StateTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StateTest.java
index b74b985..f057850 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StateTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StateTest.java
@@ -23,18 +23,44 @@
 
 @SmallTest
 public class StateTest extends AndroidTestCase {
-    public void testPushDocument() {
-        final State state = new State();
-        final DocumentInfo infoFirst = new DocumentInfo();
-        infoFirst.displayName = "firstDirectory";
-        final DocumentInfo infoSecond = new DocumentInfo();
-        infoSecond.displayName = "secondDirectory";
-        assertFalse(state.hasLocationChanged());
-        state.pushDocument(infoFirst);
-        state.pushDocument(infoSecond);
-        assertTrue(state.hasLocationChanged());
-        assertEquals("secondDirectory", state.stack.getFirst().displayName);
-        state.popDocument();
-        assertEquals("firstDirectory", state.stack.getFirst().displayName);
+
+    private static final DocumentInfo DIR_1;
+    private static final DocumentInfo DIR_2;
+
+    private State mState;
+
+    static {
+        DIR_1 = new DocumentInfo();
+        DIR_1.displayName = "firstDirectory";
+        DIR_2 = new DocumentInfo();
+        DIR_2.displayName = "secondDirectory";
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        mState = new State();
+    }
+
+    public void testInitialStateEmpty() {
+        assertFalse(mState.hasLocationChanged());
+    }
+
+    public void testPushDocument_ChangesLocation() {
+        mState.pushDocument(DIR_1);
+        mState.pushDocument(DIR_2);
+        assertTrue(mState.hasLocationChanged());
+    }
+
+    public void testPushDocument_ModifiesStack() {
+        mState.pushDocument(DIR_1);
+        mState.pushDocument(DIR_2);
+        assertEquals(DIR_2, mState.stack.getFirst());
+    }
+
+    public void testPopDocument_ModifiesStack() {
+        mState.pushDocument(DIR_1);
+        mState.pushDocument(DIR_2);
+        mState.popDocument();
+        assertEquals(DIR_1, mState.stack.getFirst());
     }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
index d609fa84..d2f8403 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/UiBot.java
@@ -21,9 +21,11 @@
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.assertFalse;
 
+import android.app.Activity;
 import android.content.Context;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.Configurator;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
 import android.support.test.uiautomator.UiObject2;
@@ -32,6 +34,7 @@
 import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.inputmethod.InputMethodManager;
 
 import junit.framework.Assert;
@@ -47,8 +50,10 @@
  * programmatically, and making assertions against the state of the UI.
  */
 class UiBot {
+    public static final String TARGET_PKG = "com.android.documentsui";
 
     private static final String TAG = "UiBot";
+    private static final String LAUNCHER_PKG = "com.android.launcher";
 
     private static final BySelector SNACK_DELETE =
             By.desc(Pattern.compile("^Deleting [0-9]+ file.+"));
@@ -66,7 +71,7 @@
     UiObject findRoot(String label) throws UiObjectNotFoundException {
         final UiSelector rootsList = new UiSelector().resourceId(
                 "com.android.documentsui:id/container_roots").childSelector(
-                new UiSelector().resourceId("android:id/list"));
+                new UiSelector().resourceId("com.android.documentsui:id/roots_list"));
 
         // We might need to expand drawer if not visible
         if (!new UiObject(rootsList).waitForExists(mTimeout)) {
@@ -190,6 +195,23 @@
         assertNotNull(getSnackbar(mContext.getString(id)));
     }
 
+    /**
+     * Asserts that the specified view or one of its descendents has focus.
+     */
+    void assertHasFocus(String resourceName) {
+        UiObject2 candidate = mDevice.findObject(By.res(resourceName));
+        assertNotNull("Expected " + resourceName + " to have focus, but it didn't.",
+            candidate.findObject(By.focused(true)));
+    }
+
+    void openDocument(String label) throws UiObjectNotFoundException {
+        int toolType = Configurator.getInstance().getToolType();
+        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER);
+        UiObject doc = findDocument(label);
+        doc.click();
+        Configurator.getInstance().setToolType(toolType);
+    }
+
     void clickDocument(String label) throws UiObjectNotFoundException {
         findDocument(label).click();
     }
@@ -245,6 +267,10 @@
         mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2);
     }
 
+    void waitForDocument(String label) throws UiObjectNotFoundException {
+        findDocument(label).waitForExists(mTimeout);
+    }
+
     void switchViewMode() {
         UiObject2 mode = menuGridMode();
         if (mode != null) {
@@ -292,7 +318,7 @@
     UiObject findDocument(String label) throws UiObjectNotFoundException {
         final UiSelector docList = new UiSelector().resourceId(
                 "com.android.documentsui:id/container_directory").childSelector(
-                        new UiSelector().resourceId("com.android.documentsui:id/list"));
+                        new UiSelector().resourceId("com.android.documentsui:id/dir_list"));
 
         // Wait for the first list item to appear
         new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
@@ -313,7 +339,7 @@
     UiObject findDocumentsList() {
         return findObject(
                 "com.android.documentsui:id/container_directory",
-                "com.android.documentsui:id/list");
+                "com.android.documentsui:id/dir_list");
     }
 
     UiObject findSearchView() {
@@ -390,4 +416,17 @@
         }
     }
 
+    void revealLauncher() {
+        mDevice.pressHome();
+        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), mTimeout);
+    }
+
+    void revealApp() {
+        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), mTimeout);
+        mDevice.waitForIdle();
+    }
+
+    void pressKey(int keyCode) {
+        mDevice.pressKeyCode(keyCode);
+    }
 }
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/UiTestEnvironment.java b/packages/DocumentsUI/tests/src/com/android/documentsui/UiTestEnvironment.java
deleted file mode 100644
index 9e30589..0000000
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/UiTestEnvironment.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.documentsui;
-
-import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
-import static com.android.documentsui.StubProvider.ROOT_0_ID;
-import static com.android.documentsui.StubProvider.ROOT_1_ID;
-
-import android.app.Instrumentation;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.RemoteException;
-import android.provider.DocumentsContract.Document;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.support.test.uiautomator.Until;
-import android.view.MotionEvent;
-
-import com.android.documentsui.model.RootInfo;
-
-/**
- * Provides basic test environment for UI tests:
- * - Launches activity
- * - Creates and gives access to test root directories and test files
- * - Cleans up the test environment
- */
-class UiTestEnvironment {
-
-    public static final int TIMEOUT = 5000;
-    public static final String NO_RENAME = "NO_RENAME";
-
-    public static final String dirName1 = "Dir1";
-    public static final String fileName1 = "file1.log";
-    public static final String fileName2 = "file12.png";
-    public static final String fileName3 = "anotherFile0.log";
-    public static final String fileName4 = "poodles.text";
-    public static final String fileNameNoRename = NO_RENAME + "file.txt";
-
-    private static final String TARGET_PKG = "com.android.documentsui";
-    private static final String LAUNCHER_PKG = "com.android.launcher";
-
-    private final UiBot mBot;
-    private final UiDevice mDevice;
-    private final Context mContext;
-
-    private  RootInfo mRootDir0;
-    private  RootInfo mRootDir1;
-    private int mDocsCountDir0;
-    private int mDocsCountDir1;
-
-    private ContentResolver mResolver;
-    private DocumentsProviderHelper mDocsHelper;
-    private ContentProviderClient mClient;
-
-    private final Instrumentation mInstrumentation;
-
-    public UiTestEnvironment(Instrumentation instrumentation) {
-        mInstrumentation = instrumentation;
-        mDevice = UiDevice.getInstance(mInstrumentation);
-        // NOTE: Must be the "target" context, else security checks in content provider will fail.
-        mContext = mInstrumentation.getTargetContext();
-        mBot = new UiBot(mDevice, mContext, TIMEOUT);
-    }
-
-/**
- * Launches default activity and waits for the application to appear.
- * @throws Exception
- */
-    public void launch() throws Exception {
-        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG);
-        launch(intent);
-    }
-
-    /**
-     * Launches activity specified by intent and waits for the application to appear.
-     * @param intent Intent describing activity to launch.
-     * @throws Exception
-     */
-    public void launch(Intent intent) throws Exception {
-        Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
-        // Start from the home screen.
-        mDevice.pressHome();
-        mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
-
-        mResolver = mContext.getContentResolver();
-        mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
-        mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
-
-        // Launch app.
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
-        // Wait for the app to appear.
-        mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
-        mDevice.waitForIdle();
-
-        resetStorage(); // Just incase a test failed and tearDown didn't happen.
-    }
-
-    public void cleanUp() throws Exception {
-        resetStorage();
-        mClient.release();
-    }
-
-    public void resetStorage() throws RemoteException {
-        mClient.call("clear", null, null);
-        mDevice.waitForIdle();
-    }
-
-    public void initTestFiles() throws RemoteException {
-        mRootDir0 = mDocsHelper.getRoot(ROOT_0_ID);
-        mRootDir1 = mDocsHelper.getRoot(ROOT_1_ID);
-
-        mDocsHelper.createFolder(mRootDir0, dirName1);
-        mDocsHelper.createDocument(mRootDir0, "text/plain", fileName1);
-        mDocsHelper.createDocument(mRootDir0, "image/png", fileName2);
-        mDocsHelper.createDocumentWithFlags(mRootDir0.documentId, "text/plain", fileNameNoRename,
-                Document.FLAG_SUPPORTS_WRITE);
-        mDocsCountDir0 = 4;
-
-        mDocsHelper.createDocument(mRootDir1, "text/plain", fileName3);
-        mDocsHelper.createDocument(mRootDir1, "text/plain", fileName4);
-        mDocsCountDir1 = 2;
-    }
-
-    public void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException {
-        bot().assertDocumentsCount(ROOT_0_ID, getDocumentsCountDir0());
-        bot().assertHasDocuments(UiTestEnvironment.fileName1, UiTestEnvironment.fileName2,
-                UiTestEnvironment.dirName1, UiTestEnvironment.fileNameNoRename);
-    }
-
-    public void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException {
-        bot().assertDocumentsCount(ROOT_1_ID, getDocumentsCountDir1());
-        bot().assertHasDocuments(UiTestEnvironment.fileName3, UiTestEnvironment.fileName4);
-    }
-
-    public UiBot bot() {
-        return mBot;
-    }
-
-    public UiDevice device() {
-        return mDevice;
-    }
-
-    public Context context() {
-        return mContext;
-    }
-
-    public RootInfo getRootDir0() {
-        return mRootDir0;
-    }
-
-    public int getDocumentsCountDir0() {
-        return mDocsCountDir0;
-    }
-
-    public int getDocumentsCountDir1() {
-        return mDocsCountDir1;
-    }
-}
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 b1cb29e..9447d9c1 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
@@ -50,7 +50,7 @@
         mCallback = new TestCallback();
         mEnv = new TestSelectionEnvironment(items);
         mAdapter = new TestDocumentsAdapter(items);
-        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_MULTIPLE);
+        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_MULTIPLE, null);
         mManager.addCallback(mCallback);
     }
 
@@ -174,7 +174,7 @@
     }
 
     public void testSingleSelectMode() {
-        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE);
+        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
         mManager.addCallback(mCallback);
         longPress(20);
         tap(13);
@@ -182,13 +182,61 @@
     }
 
     public void testSingleSelectMode_ShiftTap() {
-        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE);
+        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
         mManager.addCallback(mCallback);
         longPress(13);
         shiftTap(20);
         assertSelection(items.get(20));
     }
 
+    public void testRangeSelection() {
+        mManager.startRangeSelection(15);
+        mManager.snapRangeSelection(19);
+        assertRangeSelection(15, 19);
+    }
+
+    public void testRangeSelection_snapExpand() {
+        mManager.startRangeSelection(15);
+        mManager.snapRangeSelection(19);
+        mManager.snapRangeSelection(27);
+        assertRangeSelection(15, 27);
+    }
+
+    public void testRangeSelection_snapContract() {
+        mManager.startRangeSelection(15);
+        mManager.snapRangeSelection(27);
+        mManager.snapRangeSelection(19);
+        assertRangeSelection(15, 19);
+    }
+
+    public void testRangeSelection_snapInvert() {
+        mManager.startRangeSelection(15);
+        mManager.snapRangeSelection(27);
+        mManager.snapRangeSelection(3);
+        assertRangeSelection(3, 15);
+    }
+
+    public void testRangeSelection_multiple() {
+        mManager.startRangeSelection(15);
+        mManager.snapRangeSelection(27);
+        mManager.endRangeSelection();
+        mManager.startRangeSelection(42);
+        mManager.snapRangeSelection(57);
+        assertSelectionSize(29);
+        assertRangeSelected(15, 27);
+        assertRangeSelected(42, 57);
+
+    }
+
+    public void testRangeSelection_singleSelect() {
+        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE, null);
+        mManager.addCallback(mCallback);
+        mManager.startRangeSelection(11);
+        mManager.snapRangeSelection(19);
+        assertSelectionSize(1);
+        assertSelection(items.get(19));
+    }
+
     public void testProvisionalSelection() {
         Selection s = mManager.getSelection();
         assertSelection();
@@ -198,24 +246,73 @@
         provisional.append(2, true);
         s.setProvisionalSelection(getItemIds(provisional));
         assertSelection(items.get(1), items.get(2));
+    }
 
-        provisional.delete(1);
-        provisional.append(3, true);
+    public void testProvisionalSelection_Replace() {
+        Selection s = mManager.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
         s.setProvisionalSelection(getItemIds(provisional));
-        assertSelection(items.get(2), items.get(3));
-
-        s.applyProvisionalSelection();
-        assertSelection(items.get(2), items.get(3));
 
         provisional.clear();
         provisional.append(3, true);
         provisional.append(4, true);
         s.setProvisionalSelection(getItemIds(provisional));
-        assertSelection(items.get(2), items.get(3), items.get(4));
+        assertSelection(items.get(3), items.get(4));
+    }
 
-        provisional.delete(3);
+    public void testProvisionalSelection_IntersectsExistingProvisionalSelection() {
+        Selection s = mManager.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
         s.setProvisionalSelection(getItemIds(provisional));
-        assertSelection(items.get(2), items.get(3), items.get(4));
+
+        provisional.clear();
+        provisional.append(1, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        assertSelection(items.get(1));
+    }
+
+    public void testProvisionalSelection_Apply() {
+        Selection s = mManager.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(1, true);
+        provisional.append(2, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        s.applyProvisionalSelection();
+        assertSelection(items.get(1), items.get(2));
+    }
+
+    public void testProvisionalSelection_Cancel() {
+        mManager.toggleSelection(items.get(1));
+        mManager.toggleSelection(items.get(2));
+        Selection s = mManager.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(3, true);
+        provisional.append(4, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        s.cancelProvisionalSelection();
+
+        // Original selection should remain.
+        assertSelection(items.get(1), items.get(2));
+    }
+
+    public void testProvisionalSelection_IntersectsAppliedSelection() {
+        mManager.toggleSelection(items.get(1));
+        mManager.toggleSelection(items.get(2));
+        Selection s = mManager.getSelection();
+
+        SparseBooleanArray provisional = new SparseBooleanArray();
+        provisional.append(2, true);
+        provisional.append(3, true);
+        s.setProvisionalSelection(getItemIds(provisional));
+        assertSelection(items.get(1), items.get(2), items.get(3));
     }
 
     private static Set<String> getItemIds(SparseBooleanArray selection) {
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/model/DocumentInfoTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/model/DocumentInfoTest.java
index a6aba7b..2481dc3 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/model/DocumentInfoTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/model/DocumentInfoTest.java
@@ -22,30 +22,36 @@
 @SmallTest
 public class DocumentInfoTest extends AndroidTestCase {
 
+    private static final DocumentInfo TEST_DOC
+            = createDocInfo("authority.a", "doc.1", "text/plain");
+
     public void testEquals() throws Exception {
-        DocumentInfo doc = createDocInfo("authority.a", "doc.1", "text/plain");
-        assertEquals(doc, doc);
+        assertEquals(TEST_DOC, TEST_DOC);
+        assertEquals(TEST_DOC, createDocInfo("authority.a", "doc.1", "text/plain"));
+    }
+
+    public void testEquals_HandlesNulls() throws Exception {
+        assertFalse(TEST_DOC.equals(null));
+    }
+
+    public void testEquals_HandlesNullFields() throws Exception {
+        assertFalse(TEST_DOC.equals(new DocumentInfo()));
+        assertFalse(new DocumentInfo().equals(TEST_DOC));
     }
 
     public void testNotEquals_differentAuthority() throws Exception {
-        DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
-        DocumentInfo docB = createDocInfo("authority.b", "doc.1", "text/plain");
-        assertFalse(docA.equals(docB));
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.b", "doc.1", "text/plain")));
     }
 
     public void testNotEquals_differentDocId() throws Exception {
-        DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
-        DocumentInfo docB = createDocInfo("authority.a", "doc.2", "text/plain");
-        assertFalse(docA.equals(docB));
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.2", "text/plain")));
     }
 
     public void testNotEquals_differentMimetype() throws Exception {
-        DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
-        DocumentInfo docB = createDocInfo("authority.a", "doc.1", "image/png");
-        assertFalse(docA.equals(docB));
+        assertFalse(TEST_DOC.equals(createDocInfo("authority.a", "doc.1", "image/png")));
     }
 
-    private DocumentInfo createDocInfo(String authority, String docId, String mimeType) {
+    private static DocumentInfo createDocInfo(String authority, String docId, String mimeType) {
         DocumentInfo doc = new DocumentInfo();
         doc.authority = authority;
         doc.documentId = docId;
diff --git a/packages/ExternalStorageProvider/res/values/strings.xml b/packages/ExternalStorageProvider/res/values/strings.xml
index e48436e..8b16d3c 100644
--- a/packages/ExternalStorageProvider/res/values/strings.xml
+++ b/packages/ExternalStorageProvider/res/values/strings.xml
@@ -20,6 +20,6 @@
 
     <!-- Title for documents backend that offers internal storage. [CHAR LIMIT=24] -->
     <string name="root_internal_storage">Internal storage</string>
-    <!-- Title for user home dir. [CHAR LIMIT=24] -->
-    <string name="root_home">Home</string>
+    <!-- Title for directory in which a user may store their own documents and files. [CHAR LIMIT=24] -->
+    <string name="root_documents">Documents</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index f89934d..97dfd47 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -199,7 +199,7 @@
             final RootInfo root = new RootInfo();
             root.rootId = ROOT_ID_HOME;
             mRoots.put(root.rootId, root);
-            root.title = getContext().getString(R.string.root_home);
+            root.title = getContext().getString(R.string.root_documents);
 
             // Only report bytes on *volumes*...as a matter of policy.
             root.reportAvailableBytes = false;
@@ -214,9 +214,9 @@
             // Create the "Home" directory on disk, but don't the localized root.title
             // since the directories shouldn't be localized.
             root.visiblePath = new File(
-                    primaryVolume.getPathForUser(userId), Environment.DIRECTORY_HOME);
+                    primaryVolume.getPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
             root.path = new File(
-                    primaryVolume.getInternalPathForUser(userId), root.rootId);
+                    primaryVolume.getInternalPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
             try {
                 root.docId = getDocIdForFile(root.path);
             } catch (FileNotFoundException e) {
diff --git a/packages/MtpDocumentsProvider/res/values/strings.xml b/packages/MtpDocumentsProvider/res/values/strings.xml
index 43a420c..f3a3fcf 100644
--- a/packages/MtpDocumentsProvider/res/values/strings.xml
+++ b/packages/MtpDocumentsProvider/res/values/strings.xml
@@ -25,4 +25,8 @@
     <string name="accessing_notification_title">Accessing files from <xliff:g id="device_model" example="Nexus 9">%1$s</xliff:g></string>
     <!-- Description of notification showing Files app is accessing files in a MTP device. [CHAR LIMIT=60]-->
     <string name="accessing_notification_description">Don\'t disconnect the device</string>
+    <!-- Error message shown in Files app when the connected MTP device is busy. [CHAR LIMIT=150]-->
+    <string name="error_busy_device">The other device is busy. You can\'t transfer files until it\'s available.</string>
+    <!-- Error message shown in Files app when the connected MTP device may be locked. [CHAR LIMIT=150]-->
+    <string name="error_locked_device">No files found. The other device may be locked. If so, unlock it and try again.</string>
 </resources>
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index ef1e8e2..90b5c09 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -18,7 +18,6 @@
 
 import android.content.ContentResolver;
 import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
 import android.mtp.MtpObjectInfo;
 import android.net.Uri;
 import android.os.Bundle;
@@ -262,31 +261,39 @@
             if (objectInfoList.length == 0 || getState() != STATE_LOADING) {
                 return;
             }
-            if (mNumLoaded == 0) {
-                mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId);
-            }
-            try {
+            try{
+                if (mNumLoaded == 0) {
+                    mDatabase.getMapper().startAddingDocuments(mIdentifier.mDocumentId);
+                }
                 mDatabase.getMapper().putChildDocuments(
                         mIdentifier.mDeviceId, mIdentifier.mDocumentId, objectInfoList);
                 mNumLoaded += objectInfoList.length;
-            } catch (SQLiteException exp) {
-                mError = exp;
-                mNumLoaded = 0;
-            }
-            if (getState() != STATE_LOADING) {
-                mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId);
+                if (getState() != STATE_LOADING) {
+                    mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId);
+                }
+            } catch (FileNotFoundException exception) {
+                setErrorInternal(exception);
             }
         }
 
-        void setError(Exception message) {
+        void setError(Exception error) {
             final int lastState = getState();
-            mError = message;
-            mNumLoaded = 0;
+            setErrorInternal(error);
             if (lastState == STATE_LOADING) {
-                mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId);
+                try {
+                    mDatabase.getMapper().stopAddingDocuments(mIdentifier.mDocumentId);
+                } catch (FileNotFoundException exception) {
+                    setErrorInternal(exception);
+                }
             }
         }
 
+        private void setErrorInternal(Exception error) {
+            Log.e(MtpDocumentsProvider.TAG, "Error in DocumentLoader thread", error);
+            mError = error;
+            mNumLoaded = 0;
+        }
+
         private Uri createUri() {
             return DocumentsContract.buildChildDocumentsUri(
                     MtpDocumentsProvider.AUTHORITY, mIdentifier.mDocumentId);
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
index 3faa8f4..5e3417a 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/Mapper.java
@@ -16,8 +16,6 @@
 
 package com.android.mtp;
 
-import static com.android.mtp.MtpDatabaseConstants.*;
-
 import android.annotation.Nullable;
 import android.content.ContentValues;
 import android.database.Cursor;
@@ -26,13 +24,15 @@
 import android.mtp.MtpObjectInfo;
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Root;
+import android.util.ArraySet;
+import android.util.Log;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.io.FileNotFoundException;
+import java.util.Set;
 
+import static com.android.mtp.MtpDatabaseConstants.*;
 import static com.android.mtp.MtpDatabase.strings;
 
 /**
@@ -44,11 +44,9 @@
     private final MtpDatabase mDatabase;
 
     /**
-     * Mapping mode for a parent. The key is document ID of parent, or null for root documents.
-     * Methods operate the state needs to be synchronized.
-     * TODO: Replace this with unboxing int map.
+     * IDs which currently Mapper operates mapping for.
      */
-    private final Map<String, Integer> mMappingMode = new HashMap<>();
+    private final Set<String> mInMappingIds = new ArraySet<>();
 
     Mapper(MtpDatabase database) {
         mDatabase = database;
@@ -56,11 +54,12 @@
 
     /**
      * Puts device information to database.
+     *
      * @return If device is added to the database.
+     * @throws FileNotFoundException
      */
-    synchronized boolean putDeviceDocument(MtpDeviceRecord device) {
+    synchronized boolean putDeviceDocument(MtpDeviceRecord device) throws FileNotFoundException {
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
-        Preconditions.checkState(mMappingMode.containsKey(/* no parent for root */ null));
         database.beginTransaction();
         try {
             final ContentValues[] valuesList = new ContentValues[1];
@@ -69,12 +68,12 @@
             extraValuesList[0] = new ContentValues();
             MtpDatabase.getDeviceDocumentValues(valuesList[0], extraValuesList[0], device);
             final boolean changed = putDocuments(
+                    null,
                     valuesList,
                     extraValuesList,
                     COLUMN_PARENT_DOCUMENT_ID + " IS NULL",
                     EMPTY_ARGS,
-                    /* heuristic */ false,
-                    COLUMN_DEVICE_ID);
+                    strings(COLUMN_DEVICE_ID, COLUMN_MAPPING_KEY));
             database.setTransactionSuccessful();
             return changed;
         } finally {
@@ -84,29 +83,17 @@
 
     /**
      * Puts root information to database.
+     *
      * @param parentDocumentId Document ID of device document.
      * @param roots List of root information.
      * @return If roots are added or removed from the database.
+     * @throws FileNotFoundException
      */
-    synchronized boolean putStorageDocuments(String parentDocumentId, MtpRoot[] roots) {
+    synchronized boolean putStorageDocuments(String parentDocumentId, MtpRoot[] roots)
+            throws FileNotFoundException {
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
         database.beginTransaction();
         try {
-            final boolean heuristic;
-            final String mapColumn;
-            Preconditions.checkState(mMappingMode.containsKey(parentDocumentId));
-            switch (mMappingMode.get(parentDocumentId)) {
-                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];
             final ContentValues[] extraValuesList = new ContentValues[roots.length];
             for (int i = 0; i < roots.length; i++) {
@@ -116,12 +103,12 @@
                         valuesList[i], extraValuesList[i], parentDocumentId, roots[i]);
             }
             final boolean changed = putDocuments(
+                    parentDocumentId,
                     valuesList,
                     extraValuesList,
-                    COLUMN_PARENT_DOCUMENT_ID + "=?",
+                    COLUMN_PARENT_DOCUMENT_ID + " = ?",
                     strings(parentDocumentId),
-                    heuristic,
-                    mapColumn);
+                    strings(COLUMN_STORAGE_ID, Document.COLUMN_DISPLAY_NAME));
 
             database.setTransactionSuccessful();
             return changed;
@@ -132,55 +119,42 @@
 
     /**
      * Puts document information to database.
+     *
      * @param deviceId Device ID
      * @param parentId Parent document ID.
      * @param documents List of document information.
+     * @throws FileNotFoundException
      */
-    synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents) {
-        final boolean heuristic;
-        final String mapColumn;
-        Preconditions.checkState(mMappingMode.containsKey(parentId));
-        switch (mMappingMode.get(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.");
-        }
+    synchronized void putChildDocuments(int deviceId, String parentId, MtpObjectInfo[] documents)
+            throws FileNotFoundException {
         final ContentValues[] valuesList = new ContentValues[documents.length];
         for (int i = 0; i < documents.length; i++) {
             valuesList[i] = new ContentValues();
-            MtpDatabase.getObjectDocumentValues(
-                    valuesList[i], deviceId, parentId, documents[i]);
+            MtpDatabase.getObjectDocumentValues(valuesList[i], deviceId, parentId, documents[i]);
         }
         putDocuments(
+                parentId,
                 valuesList,
                 null,
-                COLUMN_PARENT_DOCUMENT_ID + "=?",
+                COLUMN_PARENT_DOCUMENT_ID + " = ?",
                 strings(parentId),
-                heuristic,
-                mapColumn);
+                strings(COLUMN_OBJECT_HANDLE, Document.COLUMN_DISPLAY_NAME));
     }
 
-    @VisibleForTesting
     void clearMapping() {
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
         database.beginTransaction();
         try {
-            mDatabase.deleteDocumentsAndRootsRecursively(
-                    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);
-            database.update(TABLE_DOCUMENTS, values, null, null);
+            mInMappingIds.clear();
+            // Disconnect all device rows.
+            try {
+                startAddingDocuments(null);
+                stopAddingDocuments(null);
+            } catch (FileNotFoundException exception) {
+                Log.e(MtpDocumentsProvider.TAG, "Unexpected FileNotFoundException.", exception);
+                throw new RuntimeException(exception);
+            }
             database.setTransactionSuccessful();
-            mMappingMode.clear();
         } finally {
             database.endTransaction();
         }
@@ -193,9 +167,9 @@
      * a corresponding existing row. Otherwise it does heuristic.
      *
      * @param parentDocumentId Parent document ID or NULL for root documents.
+     * @throws FileNotFoundException
      */
-    void startAddingDocuments(@Nullable String parentDocumentId) {
-        Preconditions.checkState(!mMappingMode.containsKey(parentDocumentId));
+    void startAddingDocuments(@Nullable String parentDocumentId) throws FileNotFoundException {
         final String selection;
         final String[] args;
         if (parentDocumentId != null) {
@@ -209,25 +183,20 @@
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
         database.beginTransaction();
         try {
-            // Delete all pending rows.
-            mDatabase.deleteDocumentsAndRootsRecursively(
-                    selection + " AND " + COLUMN_ROW_STATE + "=?",
-                    DatabaseUtils.appendSelectionArgs(args, strings(ROW_STATE_PENDING)));
+            getParentOrHaltMapping(parentDocumentId);
+            Preconditions.checkState(!mInMappingIds.contains(parentDocumentId));
 
-            // Set all documents as invalidated.
+            // Set all valid documents as invalidated.
             final ContentValues values = new ContentValues();
             values.put(COLUMN_ROW_STATE, ROW_STATE_INVALIDATED);
-            database.update(TABLE_DOCUMENTS, values, selection, args);
-
-            // If we have rows that does not have MTP identifier, do heuristic mapping by name.
-            final boolean useNameForResolving = DatabaseUtils.queryNumEntries(
-                    database,
+            database.update(
                     TABLE_DOCUMENTS,
-                    selection + " AND " + COLUMN_STORAGE_ID + " IS NULL",
-                    args) > 0;
+                    values,
+                    selection + " AND " + COLUMN_ROW_STATE + " = ?",
+                    DatabaseUtils.appendSelectionArgs(args, strings(ROW_STATE_VALID)));
+
             database.setTransactionSuccessful();
-            mMappingMode.put(
-                    parentDocumentId, useNameForResolving ? MAP_BY_NAME : MAP_BY_MTP_IDENTIFIER);
+            mInMappingIds.add(parentDocumentId);
         } finally {
             database.endTransaction();
         }
@@ -241,24 +210,29 @@
      * {@link #stopAddingDocuments(String)} turns the pending rows into 'valid'
      * rows. If the methods adds rows to database, it updates valueList with correct document ID.
      *
+     * @param parentId Parent document ID.
      * @param valuesList Values for documents to be stored in the database.
      * @param rootExtraValuesList Values for root extra to be stored in the database.
      * @param selection SQL where closure to select rows that shares the same parent.
      * @param args Argument for selection SQL.
-     * @param heuristic Whether the mapping mode is heuristic.
-     * @return Whether the method adds new rows.
+     * @return Whether the database content is changed.
+     * @throws FileNotFoundException When parentId is not registered in the database.
      */
     private boolean putDocuments(
+            String parentId,
             ContentValues[] valuesList,
             @Nullable ContentValues[] rootExtraValuesList,
             String selection,
             String[] args,
-            boolean heuristic,
-            String mappingKey) {
+            String[] mappingKeys) throws FileNotFoundException {
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
-        boolean added = false;
+        boolean changed = false;
         database.beginTransaction();
         try {
+            getParentOrHaltMapping(parentId);
+            Preconditions.checkState(mInMappingIds.contains(parentId));
+            final ContentValues oldRowSnapshot = new ContentValues();
+            final ContentValues newRowSnapshot = new ContentValues();
             for (int i = 0; i < valuesList.length; i++) {
                 final ContentValues values = valuesList[i];
                 final ContentValues rootExtraValues;
@@ -267,35 +241,23 @@
                 } else {
                     rootExtraValues = null;
                 }
-                final Cursor candidateCursor = database.query(
-                        TABLE_DOCUMENTS,
-                        strings(Document.COLUMN_DOCUMENT_ID),
-                        selection + " AND " +
-                        COLUMN_ROW_STATE + "=? AND " +
-                        mappingKey + "=?",
-                        DatabaseUtils.appendSelectionArgs(
-                                args,
-                                strings(ROW_STATE_INVALIDATED, values.getAsString(mappingKey))),
-                        null,
-                        null,
-                        null,
-                        "1");
-                try {
+                try (final Cursor candidateCursor =
+                        queryCandidate(selection, args, mappingKeys, values)) {
                     final long rowId;
-                    if (candidateCursor.getCount() == 0) {
+                    if (candidateCursor == null) {
                         rowId = database.insert(TABLE_DOCUMENTS, null, values);
-                        added = true;
-                    } else if (!heuristic) {
+                        changed = true;
+                    } else {
                         candidateCursor.moveToNext();
                         rowId = candidateCursor.getLong(0);
+                        if (!changed) {
+                            mDatabase.writeRowSnapshot(String.valueOf(rowId), oldRowSnapshot);
+                        }
                         database.update(
                                 TABLE_DOCUMENTS,
                                 values,
                                 SELECTION_DOCUMENT_ID,
                                 strings(rowId));
-                    } else {
-                        values.put(COLUMN_ROW_STATE, ROW_STATE_PENDING);
-                        rowId = database.insertOrThrow(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.
@@ -304,13 +266,20 @@
                         rootExtraValues.put(Root.COLUMN_ROOT_ID, rowId);
                         database.replace(TABLE_ROOT_EXTRA, null, rootExtraValues);
                     }
-                } finally {
-                    candidateCursor.close();
+
+                    if (!changed) {
+                        mDatabase.writeRowSnapshot(String.valueOf(rowId), newRowSnapshot);
+                        // Put row state as string because SQLite returns snapshot values as string.
+                        oldRowSnapshot.put(COLUMN_ROW_STATE, String.valueOf(ROW_STATE_VALID));
+                        if (!oldRowSnapshot.equals(newRowSnapshot)) {
+                            changed = true;
+                        }
+                    }
                 }
             }
 
             database.setTransactionSuccessful();
-            return added;
+            return changed;
         } finally {
             database.endTransaction();
         }
@@ -320,119 +289,48 @@
      * 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 parentId Parent document ID or null for root documents.
      * @return Whether the methods adds or removed visible rows.
+     * @throws FileNotFoundException
      */
-    boolean stopAddingDocuments(@Nullable String parentId) {
-        Preconditions.checkState(mMappingMode.containsKey(parentId));
+    boolean stopAddingDocuments(@Nullable String parentId) throws FileNotFoundException {
         final String selection;
         final String[] args;
         if (parentId != null) {
-            selection = COLUMN_PARENT_DOCUMENT_ID + "=?";
+            selection = COLUMN_PARENT_DOCUMENT_ID + " = ?";
             args = strings(parentId);
         } else {
             selection = COLUMN_PARENT_DOCUMENT_ID + " IS NULL";
             args = EMPTY_ARGS;
         }
-        final String groupKey;
-        switch (mMappingMode.get(parentId)) {
-            case MAP_BY_MTP_IDENTIFIER:
-                groupKey = parentId != null ? COLUMN_OBJECT_HANDLE : COLUMN_STORAGE_ID;
-                break;
-            case MAP_BY_NAME:
-                groupKey = Document.COLUMN_DISPLAY_NAME;
-                break;
-            default:
-                throw new Error("Unexpected mapping state.");
-        }
-        mMappingMode.remove(parentId);
+
         final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
         database.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 = database.query(
-                    TABLE_DOCUMENTS,
-                    new String[] {
-                            "group_concat(" + invalidatedIdQuery + ")",
-                            "group_concat(" + pendingIdQuery + ")"
-                    },
-                    selection,
-                    args,
-                    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);
-                database.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);
-                    database.update(
-                            TABLE_ROOT_EXTRA,
-                            values,
-                            SELECTION_ROOT_ID,
-                            new String[] { invalidatedId });
-                }
-
-                // Delete 'pending' row.
-                mDatabase.deleteDocumentsAndRootsRecursively(
-                        SELECTION_DOCUMENT_ID, new String[] { pendingId });
-            }
-            mergingCursor.close();
+            final Identifier parentIdentifier = getParentOrHaltMapping(parentId);
+            Preconditions.checkState(mInMappingIds.contains(parentId));
+            mInMappingIds.remove(parentId);
 
             boolean changed = false;
-
-            // Delete all invalidated rows that cannot be mapped.
-            if (mDatabase.deleteDocumentsAndRootsRecursively(
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    DatabaseUtils.appendSelectionArgs(strings(ROW_STATE_INVALIDATED), args))) {
-                changed = true;
+            // Delete/disconnect all invalidated rows that cannot be mapped.
+            final boolean keepUnmatchedDocument =
+                    parentIdentifier == null ||
+                    parentIdentifier.mDocumentType == DOCUMENT_TYPE_DEVICE;
+            if (keepUnmatchedDocument) {
+                if (mDatabase.disconnectDocumentsRecursively(
+                        COLUMN_ROW_STATE + " = ? AND " + selection,
+                        DatabaseUtils.appendSelectionArgs(strings(ROW_STATE_INVALIDATED), args))) {
+                    changed = true;
+                }
+            } else {
+                if (mDatabase.deleteDocumentsAndRootsRecursively(
+                        COLUMN_ROW_STATE + " = ? AND " + selection,
+                        DatabaseUtils.appendSelectionArgs(strings(ROW_STATE_INVALIDATED), args))) {
+                    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 (database.update(
-                    TABLE_DOCUMENTS,
-                    values,
-                    COLUMN_ROW_STATE + " = ? AND " + selection,
-                    DatabaseUtils.appendSelectionArgs(strings(ROW_STATE_PENDING), args)) != 0) {
-                changed = true;
-            }
             database.setTransactionSuccessful();
             return changed;
         } finally {
@@ -441,38 +339,80 @@
     }
 
     /**
-     * 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.
+     * Queries candidate for each mappingKey, and returns the first cursor that includes a
+     * candidate.
+     *
+     * @param selection Pre-selection for candidate.
+     * @param args Arguments for selection.
+     * @param mappingKeys List of mapping key columns.
+     * @param values Values of document that Mapper tries to map.
+     * @return Cursor for mapping candidate or null when Mapper does not find any candidate.
      */
-    private void getFirstRow(String table, String selection, String[] args, ContentValues values) {
-        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
-        values.clear();
-        final Cursor cursor = database.query(table, null, selection, args, null, null, null, "1");
-        try {
-            if (cursor.getCount() == 0) {
-                return;
+    private @Nullable Cursor queryCandidate(
+            String selection, String[] args, String[] mappingKeys, ContentValues values) {
+        for (final String mappingKey : mappingKeys) {
+            final Cursor candidateCursor = queryCandidate(selection, args, mappingKey, values);
+            if (candidateCursor.getCount() == 0) {
+                candidateCursor.close();
+                continue;
             }
-            cursor.moveToNext();
-            DatabaseUtils.cursorRowToContentValues(cursor, values);
-        } finally {
-            cursor.close();
+            return candidateCursor;
         }
+        return null;
     }
 
     /**
-     * Gets SQL expression that represents the given value or NULL depends on the row state.
-     * You must pass static constants to this methods otherwise you may be suffered from SQL
-     * injections.
-     * @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.
+     * Looks for mapping candidate with given mappingKey.
+     *
+     * @param selection Pre-selection for candidate.
+     * @param args Arguments for selection.
+     * @param mappingKey Column name of mapping key.
+     * @param values Values of document that Mapper tries to map.
+     * @return Cursor for mapping candidate.
      */
-    private static String createStateFilter(int state, String a) {
-        return "CASE WHEN " + COLUMN_ROW_STATE + " = " + Integer.toString(state) +
-                " THEN " + a + " ELSE NULL END";
+    private Cursor queryCandidate(
+            String selection, String[] args, String mappingKey, ContentValues values) {
+        final SQLiteDatabase database = mDatabase.getSQLiteDatabase();
+        return database.query(
+                TABLE_DOCUMENTS,
+                strings(Document.COLUMN_DOCUMENT_ID),
+                selection + " AND " +
+                COLUMN_ROW_STATE + " IN (?, ?) AND " +
+                mappingKey + " = ?",
+                DatabaseUtils.appendSelectionArgs(
+                        args,
+                        strings(ROW_STATE_INVALIDATED,
+                                ROW_STATE_DISCONNECTED,
+                                values.getAsString(mappingKey))),
+                null,
+                null,
+                null,
+                "1");
+    }
+
+    /**
+     * Returns the parent identifier from parent document ID if the parent ID is found in the
+     * database. Otherwise it halts mapping and throws FileNotFoundException.
+     *
+     * @param parentId Parent document ID
+     * @return Parent identifier
+     * @throws FileNotFoundException
+     */
+    private @Nullable Identifier getParentOrHaltMapping(
+            @Nullable String parentId) throws FileNotFoundException {
+        if (parentId == null) {
+            return null;
+        }
+        try {
+            final Identifier identifier = mDatabase.createIdentifier(parentId);
+            if (mDatabase.getRowState(parentId) == ROW_STATE_DISCONNECTED) {
+                throw new FileNotFoundException(
+                        "document: " + parentId + " is in disconnected device.");
+            }
+            return identifier;
+        } catch (FileNotFoundException error) {
+            mInMappingIds.remove(parentId);
+            throw error;
+        }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
index 8a3ebef..441b9a7 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java
@@ -37,6 +37,7 @@
 import android.provider.DocumentsContract.Root;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 
 import java.io.FileNotFoundException;
 import java.util.Objects;
@@ -219,7 +220,7 @@
         return mDatabase.query(
                 TABLE_DOCUMENTS,
                 columnNames,
-                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_DOCUMENT_TYPE + "=?",
+                COLUMN_ROW_STATE + " IN (?, ?) AND " + COLUMN_DOCUMENT_TYPE + " = ?",
                 strings(ROW_STATE_VALID, ROW_STATE_INVALIDATED, DOCUMENT_TYPE_STORAGE),
                 null,
                 null,
@@ -244,15 +245,16 @@
     }
 
     /**
-     * Returns identifier of single storage if given document points device and it has only one
-     * storage. Otherwise null.
+     * Returns document IDs of storages under the given device document.
      *
-     * @param documentId Document ID that may point a device.
-     * @return Identifier for single storage or null.
+     * @param documentId Document ID that points a device.
+     * @return Storage document IDs.
      * @throws FileNotFoundException The given document ID is not registered in database.
      */
-    @Nullable Identifier getSingleStorageIdentifier(String documentId)
+    String[] getStorageDocumentIds(String documentId)
             throws FileNotFoundException {
+        Preconditions.checkArgument(createIdentifier(documentId).mDocumentType ==
+                DOCUMENT_TYPE_DEVICE);
         // Check if the parent document is device that has single storage.
         try (final Cursor cursor = mDatabase.query(
                 TABLE_DOCUMENTS,
@@ -267,12 +269,11 @@
                 null,
                 null,
                 null)) {
-            if (cursor.getCount() == 1) {
-                cursor.moveToNext();
-                return createIdentifier(cursor.getString(0));
-            } else {
-                return null;
+            final String[] ids = new String[cursor.getCount()];
+            for (int i = 0; cursor.moveToNext(); i++) {
+                ids[i] = cursor.getString(0);
             }
+            return ids;
         }
     }
 
@@ -294,15 +295,6 @@
                 "1");
     }
 
-    /**
-     * Remove all rows belong to a device.
-     * @param deviceId Device ID.
-     */
-    void removeDeviceRows(int deviceId) {
-        // Call non-recursive version because it anyway deletes all rows in the devices.
-        deleteDocumentsAndRoots(COLUMN_DEVICE_ID + "=?", strings(deviceId));
-    }
-
     @Nullable String getDocumentIdForDevice(int deviceId) {
         final Cursor cursor = mDatabase.query(
                 TABLE_DOCUMENTS,
@@ -344,13 +336,33 @@
             if (cursor.moveToNext()) {
                 return createIdentifier(cursor.getString(0));
             } else {
-                throw new FileNotFoundException("Cannot find a row having ID=" + documentId);
+                throw new FileNotFoundException("Cannot find a row having ID = " + documentId);
             }
         } finally {
             cursor.close();
         }
     }
 
+    String getDeviceDocumentId(int deviceId) throws FileNotFoundException {
+        try (final Cursor cursor = mDatabase.query(
+                TABLE_DOCUMENTS,
+                strings(Document.COLUMN_DOCUMENT_ID),
+                COLUMN_DEVICE_ID + " = ? AND " + COLUMN_DOCUMENT_TYPE + " = ? AND " +
+                COLUMN_ROW_STATE + " != ?",
+                strings(deviceId, DOCUMENT_TYPE_DEVICE, ROW_STATE_DISCONNECTED),
+                null,
+                null,
+                null,
+                "1")) {
+            if (cursor.getCount() > 0) {
+                cursor.moveToNext();
+                return cursor.getString(0);
+            } else {
+                throw new FileNotFoundException("The device ID not found: " + deviceId);
+            }
+        }
+    }
+
     /**
      * Adds new document under the parent.
      * The method does not affect invalidated and pending documents because we know the document is
@@ -438,7 +450,7 @@
             try {
                 while (cursor.moveToNext()) {
                     if (deleteDocumentsAndRootsRecursively(
-                            COLUMN_PARENT_DOCUMENT_ID + "=?",
+                            COLUMN_PARENT_DOCUMENT_ID + " = ?",
                             strings(cursor.getString(0)))) {
                         changed = true;
                     }
@@ -456,7 +468,43 @@
         }
     }
 
-    private boolean deleteDocumentsAndRoots(String selection, String[] args) {
+    /**
+     * Marks the documents and their child as disconnected documents.
+     * @param selection
+     * @param args
+     * @return True if at least one row is updated.
+     */
+    boolean disconnectDocumentsRecursively(String selection, String[] args) {
+        mDatabase.beginTransaction();
+        try {
+            boolean changed = false;
+            try (final Cursor cursor = mDatabase.query(
+                    TABLE_DOCUMENTS,
+                    strings(Document.COLUMN_DOCUMENT_ID),
+                    selection,
+                    args,
+                    null,
+                    null,
+                    null)) {
+                while (cursor.moveToNext()) {
+                    if (disconnectDocumentsRecursively(
+                            COLUMN_PARENT_DOCUMENT_ID + " = ?",
+                            strings(cursor.getString(0)))) {
+                        changed = true;
+                    }
+                }
+            }
+            if (disconnectDocuments(selection, args)) {
+                changed = true;
+            }
+            mDatabase.setTransactionSuccessful();
+            return changed;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    boolean deleteDocumentsAndRoots(String selection, String[] args) {
         mDatabase.beginTransaction();
         try {
             int deleted = 0;
@@ -481,6 +529,58 @@
         }
     }
 
+    boolean disconnectDocuments(String selection, String[] args) {
+        mDatabase.beginTransaction();
+        try {
+            final ContentValues values = new ContentValues();
+            values.put(COLUMN_ROW_STATE, ROW_STATE_DISCONNECTED);
+            values.putNull(COLUMN_DEVICE_ID);
+            values.putNull(COLUMN_STORAGE_ID);
+            values.putNull(COLUMN_OBJECT_HANDLE);
+            final boolean updated = mDatabase.update(TABLE_DOCUMENTS, values, selection, args) != 0;
+            mDatabase.setTransactionSuccessful();
+            return updated;
+        } finally {
+            mDatabase.endTransaction();
+        }
+    }
+
+    int getRowState(String documentId) throws FileNotFoundException {
+        try (final Cursor cursor = mDatabase.query(
+                TABLE_DOCUMENTS,
+                strings(COLUMN_ROW_STATE),
+                SELECTION_DOCUMENT_ID,
+                strings(documentId),
+                null,
+                null,
+                null)) {
+            if (cursor.getCount() == 0) {
+                throw new FileNotFoundException();
+            }
+            cursor.moveToNext();
+            return cursor.getInt(0);
+        }
+    }
+
+    void writeRowSnapshot(String documentId, ContentValues values) throws FileNotFoundException {
+        try (final Cursor cursor = mDatabase.query(
+                JOIN_ROOTS,
+                strings("*"),
+                SELECTION_DOCUMENT_ID,
+                strings(documentId),
+                null,
+                null,
+                null,
+                "1")) {
+            if (cursor.getCount() == 0) {
+                throw new FileNotFoundException();
+            }
+            cursor.moveToNext();
+            values.clear();
+            DatabaseUtils.cursorRowToContentValues(cursor, values);
+        }
+    }
+
     private static class OpenHelper extends SQLiteOpenHelper {
         public OpenHelper(Context context, int flags) {
             super(context,
@@ -497,7 +597,9 @@
 
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            throw new UnsupportedOperationException();
+            db.execSQL("DROP TABLE " + TABLE_DOCUMENTS);
+            db.execSQL("DROP TABLE " + TABLE_ROOT_EXTRA);
+            onCreate(db);
         }
     }
 
@@ -517,6 +619,7 @@
         values.putNull(COLUMN_PARENT_DOCUMENT_ID);
         values.put(COLUMN_ROW_STATE, ROW_STATE_VALID);
         values.put(COLUMN_DOCUMENT_TYPE, DOCUMENT_TYPE_DEVICE);
+        values.put(COLUMN_MAPPING_KEY, device.deviceKey);
         values.put(Document.COLUMN_MIME_TYPE, Document.MIME_TYPE_DIR);
         values.put(Document.COLUMN_DISPLAY_NAME, device.name);
         values.putNull(Document.COLUMN_SUMMARY);
@@ -614,7 +717,12 @@
         if (formatCodeMimeType != null) {
             return formatCodeMimeType;
         }
-        return MediaFile.getMimeTypeForFile(info.getName());
+        final String mediaFileMimeType = MediaFile.getMimeTypeForFile(info.getName());
+        if (mediaFileMimeType != null) {
+            return mediaFileMimeType;
+        }
+        // We don't know the file type.
+        return "application/octet-stream";
     }
 
     static String[] strings(Object... args) {
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
index 3cfb82f..ff4b89f 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java
@@ -30,7 +30,7 @@
  * Class containing MtpDatabase constants.
  */
 class MtpDatabaseConstants {
-    static final int DATABASE_VERSION = 1;
+    static final int DATABASE_VERSION = 4;
     static final String DATABASE_NAME = "database";
 
     static final int FLAG_DATABASE_IN_MEMORY = 1;
@@ -62,6 +62,7 @@
     static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id";
     static final String COLUMN_DOCUMENT_TYPE = "document_type";
     static final String COLUMN_ROW_STATE = "row_state";
+    static final String COLUMN_MAPPING_KEY = "column_mapping_key";
 
     /**
      * The state represents that the row has a valid object handle.
@@ -78,22 +79,10 @@
     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.
+     * The documents are of device/storage that are disconnected now. The documents are invisible
+     * but their document ID will be reuse when the device/storage is connected again.
      */
-    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 int ROW_STATE_DISCONNECTED = 2;
 
     @IntDef(value = { DOCUMENT_TYPE_DEVICE, DOCUMENT_TYPE_STORAGE, DOCUMENT_TYPE_OBJECT })
     @Retention(RetentionPolicy.SOURCE)
@@ -121,13 +110,14 @@
             "CREATE TABLE " + TABLE_DOCUMENTS + " (" +
             Document.COLUMN_DOCUMENT_ID +
                 " INTEGER PRIMARY KEY AUTOINCREMENT," +
-            COLUMN_DEVICE_ID + " INTEGER NOT NULL," +
+            COLUMN_DEVICE_ID + " INTEGER," +
             COLUMN_STORAGE_ID + " INTEGER," +
             COLUMN_OBJECT_HANDLE + " INTEGER," +
             COLUMN_PARENT_DOCUMENT_ID + " INTEGER," +
             COLUMN_ROW_STATE + " INTEGER NOT NULL," +
             COLUMN_DOCUMENT_TYPE + " INTEGER NOT NULL," +
-            Document.COLUMN_MIME_TYPE + " TEXT," +
+            COLUMN_MAPPING_KEY + " STRING," +
+            Document.COLUMN_MIME_TYPE + " TEXT NOT NULL," +
             Document.COLUMN_DISPLAY_NAME + " TEXT NOT NULL," +
             Document.COLUMN_SUMMARY + " TEXT," +
             Document.COLUMN_LAST_MODIFIED + " INTEGER," +
@@ -176,7 +166,7 @@
 
     private static String createJoinFromClosure(
             String table1, String table2, String column1, String column2) {
-        return table1 + " INNER JOIN " + table2 +
+        return table1 + " LEFT JOIN " + table2 +
                 " ON " + table1 + "." + column1 + " = " + table2 + "." + column2;
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
index fa99a38..71716bd 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDeviceRecord.java
@@ -21,17 +21,20 @@
 class MtpDeviceRecord {
     public final int deviceId;
     public final String name;
+    public final @Nullable String deviceKey;
     public final boolean opened;
     public final MtpRoot[] roots;
     public final @Nullable int[] operationsSupported;
     public final @Nullable int[] eventsSupported;
 
-    MtpDeviceRecord(int deviceId, String name, boolean opened, MtpRoot[] roots,
-                    @Nullable int[] operationsSupported, @Nullable int[] eventsSupported) {
+    MtpDeviceRecord(int deviceId, String name, @Nullable String deviceKey, boolean opened,
+                    MtpRoot[] roots, @Nullable int[] operationsSupported,
+                    @Nullable int[] eventsSupported) {
         this.deviceId = deviceId;
         this.name = name;
         this.opened = opened;
         this.roots = roots;
+        this.deviceKey = deviceKey;
         this.operationsSupported = operationsSupported;
         this.eventsSupported = eventsSupported;
     }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 0338454..db1671d 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -20,10 +20,12 @@
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.database.MatrixCursor;
 import android.graphics.Point;
 import android.media.MediaFile;
 import android.mtp.MtpConstants;
 import android.mtp.MtpObjectInfo;
+import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.storage.StorageManager;
@@ -35,6 +37,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.mtp.exceptions.BusyDeviceException;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -163,17 +166,25 @@
         try {
             openDevice(parentIdentifier.mDeviceId);
             if (parentIdentifier.mDocumentType == MtpDatabaseConstants.DOCUMENT_TYPE_DEVICE) {
-                final Identifier singleStorageIdentifier =
-                        mDatabase.getSingleStorageIdentifier(parentDocumentId);
-                if (singleStorageIdentifier == null) {
+                final String[] storageDocIds = mDatabase.getStorageDocumentIds(parentDocumentId);
+                if (storageDocIds.length == 0) {
+                    // Remote device does not provide storages. Maybe it is locked.
+                    return createErrorCursor(projection, R.string.error_locked_device);
+                } else if (storageDocIds.length > 1) {
                     // Returns storage list from database.
                     return mDatabase.queryChildDocuments(projection, parentDocumentId);
                 }
-                parentIdentifier = singleStorageIdentifier;
+
+                // Exact one storage is found. Skip storage and returns object in the single
+                // storage.
+                parentIdentifier = mDatabase.createIdentifier(storageDocIds[0]);
             }
+
             // Returns object list from document loader.
             return getDocumentLoader(parentIdentifier).queryChildDocuments(
                     projection, parentIdentifier);
+        } catch (BusyDeviceException exception) {
+            return createErrorCursor(projection, R.string.error_busy_device);
         } catch (IOException exception) {
             Log.e(MtpDocumentsProvider.TAG, "queryChildDocuments", exception);
             throw new FileNotFoundException(exception.getMessage());
@@ -350,9 +361,22 @@
     }
 
     /**
+     * Obtains document ID for the given device ID.
+     * @param deviceId
+     * @return document ID
+     * @throws FileNotFoundException device ID has not been build.
+     */
+    public String getDeviceDocumentId(int deviceId) throws FileNotFoundException {
+        return mDatabase.getDeviceDocumentId(deviceId);
+    }
+
+    /**
      * Resumes root scanner to handle the update of device list.
      */
     void resumeRootScanner() {
+        if (DEBUG) {
+            Log.d(MtpDocumentsProvider.TAG, "resumeRootScanner");
+        }
         mRootScanner.resume();
     }
 
@@ -442,6 +466,21 @@
         }
     }
 
+    /**
+     * Creates empty cursor with specific error message.
+     *
+     * @param projection Column names.
+     * @param stringResId String resource ID of error message.
+     * @return Empty cursor with error message.
+     */
+    private Cursor createErrorCursor(String[] projection, int stringResId) {
+        final Bundle bundle = new Bundle();
+        bundle.putString(DocumentsContract.EXTRA_ERROR, mResources.getString(stringResId));
+        final Cursor cursor = new MatrixCursor(projection);
+        cursor.setExtras(bundle);
+        return cursor;
+    }
+
     private static class DeviceToolkit {
         public final PipeManager mPipeManager;
         public final DocumentLoader mDocumentLoader;
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 5519efd..37dc761 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -33,6 +33,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.mtp.exceptions.BusyDeviceException;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -101,7 +102,8 @@
         }
 
         if (!device.open(connection)) {
-            throw new IOException("Failed to open a MTP device.");
+            // We cannot open connection when another application use the device.
+            throw new BusyDeviceException();
         }
 
         // Handle devices that fail to obtain storages just after opening a MTP session.
@@ -134,7 +136,7 @@
                 try {
                     roots = getRoots(device.getDeviceId());
                 } catch (IOException exp) {
-                    Log.e(MtpDocumentsProvider.TAG, exp.getMessage());
+                    Log.e(MtpDocumentsProvider.TAG, "Failed to open device", exp);
                     // If we failed to fetch roots for the device, we still returns device model
                     // with an empty set of roots so that the device is shown DocumentsUI as long as
                     // the device is physically connected.
@@ -149,8 +151,8 @@
                 roots = new MtpRoot[0];
             }
             devices.add(new MtpDeviceRecord(
-                    device.getDeviceId(), name, opened, roots, operationsSupported,
-                    eventsSupported));
+                    device.getDeviceId(), name, device.getSerialNumber(), opened, roots,
+                    operationsSupported, eventsSupported));
         }
         return devices.toArray(new MtpDeviceRecord[devices.size()]);
     }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
index c7206a7..84745b2 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
@@ -17,10 +17,15 @@
 package com.android.mtp;
 
 import android.app.Activity;
-import android.content.ComponentName;
 import android.content.Intent;
+import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbManager;
+import android.net.Uri;
 import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.util.Log;
+
+import java.io.IOException;
 
 /**
  * Invisible activity to receive intents.
@@ -33,14 +38,21 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(getIntent().getAction())) {
-            // TODO: To obtain data URI for the attached device, we need to wait until RootScanner
-            // found the device and add it to database. Set correct root URI, and use ACTION_BROWSE
-            // to launch Documents UI.
-            final Intent intent = new Intent(Intent.ACTION_MAIN);
-            intent.addCategory(Intent.CATEGORY_LAUNCHER);
-            intent.setComponent(new ComponentName(
-                    "com.android.documentsui", "com.android.documentsui.LauncherActivity"));
-            this.startActivity(intent);
+            final UsbDevice device = getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE);
+            try {
+                final MtpDocumentsProvider provider = MtpDocumentsProvider.getInstance();
+                provider.openDevice(device.getDeviceId());
+                final String deviceRootId = provider.getDeviceDocumentId(device.getDeviceId());
+                final Uri uri = DocumentsContract.buildRootUri(
+                        MtpDocumentsProvider.AUTHORITY, deviceRootId);
+
+                final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
+                intent.setData(uri);
+                intent.addCategory(Intent.CATEGORY_DEFAULT);
+                this.startActivity(intent);
+            } catch (IOException exception) {
+                Log.e(MtpDocumentsProvider.TAG, "Failed to open device", exception);
+            }
         }
         finish();
     }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
index a4c3cf4..a48bf12 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/RootScanner.java
@@ -22,6 +22,7 @@
 import android.provider.DocumentsContract;
 import android.util.Log;
 
+import java.io.FileNotFoundException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -70,8 +71,7 @@
      * Notifies a change of the roots list via ContentResolver.
      */
     void notifyChange() {
-        final Uri uri =
-                DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
+        final Uri uri = DocumentsContract.buildRootsUri(MtpDocumentsProvider.AUTHORITY);
         mResolver.notifyChange(uri, null, false);
     }
 
@@ -123,14 +123,22 @@
 
                 // Update devices.
                 final MtpDeviceRecord[] devices = mManager.getDevices();
-                mDatabase.getMapper().startAddingDocuments(null /* parentDocumentId */);
-                for (final MtpDeviceRecord device : devices) {
-                    if (mDatabase.getMapper().putDeviceDocument(device)) {
+                try {
+                    mDatabase.getMapper().startAddingDocuments(null /* parentDocumentId */);
+                    for (final MtpDeviceRecord device : devices) {
+                        if (mDatabase.getMapper().putDeviceDocument(device)) {
+                            changed = true;
+                        }
+                    }
+                    if (mDatabase.getMapper().stopAddingDocuments(
+                            null /* parentDocumentId */)) {
                         changed = true;
                     }
-                }
-                if (mDatabase.getMapper().stopAddingDocuments(null /* parentDocumentId */)) {
-                    changed = true;
+                } catch (FileNotFoundException exception) {
+                    // The top root (ID is null) must exist always.
+                    // FileNotFoundException is unexpected.
+                    Log.e(MtpDocumentsProvider.TAG, "Unexpected FileNotFoundException", exception);
+                    throw new AssertionError("Unexpected exception for the top parent", exception);
                 }
 
                 // Update roots.
@@ -139,12 +147,17 @@
                     if (documentId == null) {
                         continue;
                     }
-                    mDatabase.getMapper().startAddingDocuments(documentId);
-                    if (mDatabase.getMapper().putStorageDocuments(documentId, device.roots)) {
-                        changed = true;
-                    }
-                    if (mDatabase.getMapper().stopAddingDocuments(documentId)) {
-                        changed = true;
+                    try {
+                        mDatabase.getMapper().startAddingDocuments(documentId);
+                        if (mDatabase.getMapper().putStorageDocuments(documentId, device.roots)) {
+                            changed = true;
+                        }
+                        if (mDatabase.getMapper().stopAddingDocuments(documentId)) {
+                            changed = true;
+                        }
+                    } catch (FileNotFoundException exception) {
+                        Log.e(MtpDocumentsProvider.TAG, "Parent document is gone.", exception);
+                        continue;
                     }
                 }
 
diff --git a/libs/hwui/FrameStatsObserver.h b/packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java
similarity index 68%
copy from libs/hwui/FrameStatsObserver.h
copy to packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java
index 7abc9f1..55f55b0 100644
--- a/libs/hwui/FrameStatsObserver.h
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/exceptions/BusyDeviceException.java
@@ -14,19 +14,12 @@
  * limitations under the License.
  */
 
-#pragma once
+package com.android.mtp.exceptions;
 
-#include <utils/RefBase.h>
+import java.io.IOException;
 
-#include "BufferPool.h"
-
-namespace android {
-namespace uirenderer {
-
-class FrameStatsObserver : public VirtualLightRefBase {
-public:
-    virtual void notify(BufferPool::Buffer* buffer);
-};
-
-}; // namespace uirenderer
-}; // namespace android
+/**
+ * Exception thrown when the device is busy and the requested operation cannon be completed.
+ */
+public class BusyDeviceException extends IOException {
+}
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index af1fed4..474da07 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -36,16 +36,23 @@
     private TestContentResolver mResolver;
     private DocumentLoader mLoader;
     final private Identifier mParentIdentifier = new Identifier(
-            0, 0, 0, "1", MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE);
+            0, 0, 0, "2", MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE);
 
     @Override
-    public void setUp() {
+    public void setUp() throws Exception {
         mDatabase = new MtpDatabase(getContext(), MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(
+                new MtpDeviceRecord(1, "Device", null, true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        mDatabase.getMapper().startAddingDocuments("1");
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 0, "Storage", 1000, 1000, "")
         });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
+        mDatabase.getMapper().stopAddingDocuments("1");
+
         mManager = new BlockableTestMtpManager(getContext());
         mResolver = new TestContentResolver();
         mLoader = new DocumentLoader(mManager, mResolver, mDatabase);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
index a49dc67..1df7351 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java
@@ -76,8 +76,8 @@
 
     public void testPutSingleStorageDocuments() throws Exception {
         mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", null /* deviceKey */, true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -95,7 +95,8 @@
             assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
             assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
             assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
-            assertEquals(DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
+            assertEquals(
+                    DocumentsContract.Document.MIME_TYPE_DIR, getString(cursor, COLUMN_MIME_TYPE));
             assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
             assertTrue(isNull(cursor, COLUMN_SUMMARY));
             assertTrue(isNull(cursor, COLUMN_LAST_MODIFIED));
@@ -103,7 +104,8 @@
             assertEquals(0, getInt(cursor, COLUMN_FLAGS));
             assertEquals(1000, getInt(cursor, COLUMN_SIZE));
             assertEquals(
-                    MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE, getInt(cursor, COLUMN_DOCUMENT_TYPE));
+                    MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE,
+                    getInt(cursor, COLUMN_DOCUMENT_TYPE));
 
             cursor.close();
         }
@@ -138,8 +140,10 @@
     }
 
     public void testPutStorageDocuments() throws Exception {
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+        addTestDevice();
+
+        mDatabase.getMapper().startAddingDocuments("1");
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 1, "Storage", 1000, 2000, ""),
                 new MtpRoot(0, 2, "Storage", 2000, 4000, ""),
                 new MtpRoot(0, 3, "/@#%&<>Storage", 3000, 6000,"")
@@ -150,7 +154,7 @@
             assertEquals(3, cursor.getCount());
 
             cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
             assertEquals(1, getInt(cursor, COLUMN_STORAGE_ID));
             assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
@@ -165,11 +169,11 @@
                     MtpDatabaseConstants.DOCUMENT_TYPE_STORAGE, getInt(cursor, COLUMN_DOCUMENT_TYPE));
 
             cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
 
             cursor.moveToNext();
-            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals("/@#%&<>Storage", getString(cursor, COLUMN_DISPLAY_NAME));
 
             cursor.close();
@@ -186,18 +190,21 @@
     }
 
     public void testPutChildDocuments() throws Exception {
-        mDatabase.getMapper().startAddingDocuments("parentId");
-        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        addTestDevice();
+        addTestStorage("1");
+
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", 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 = mDatabase.queryChildDocuments(COLUMN_NAMES, "parentId");
+        final Cursor cursor = mDatabase.queryChildDocuments(COLUMN_NAMES, "2");
         assertEquals(3, cursor.getCount());
 
         cursor.moveToNext();
-        assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+        assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
         assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
         assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
         assertEquals(100, getInt(cursor, COLUMN_OBJECT_HANDLE));
@@ -216,7 +223,7 @@
                 MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));
 
         cursor.moveToNext();
-        assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
+        assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
         assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
         assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
         assertEquals(101, getInt(cursor, COLUMN_OBJECT_HANDLE));
@@ -235,7 +242,7 @@
                 MtpDatabaseConstants.DOCUMENT_TYPE_OBJECT, getInt(cursor, COLUMN_DOCUMENT_TYPE));
 
         cursor.moveToNext();
-        assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
+        assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
         assertEquals(0, getInt(cursor, COLUMN_DEVICE_ID));
         assertEquals(0, getInt(cursor, COLUMN_STORAGE_ID));
         assertEquals(102, getInt(cursor, COLUMN_OBJECT_HANDLE));
@@ -263,8 +270,10 @@
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
 
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+        // Add device and two storages.
+        addTestDevice();
+        mDatabase.getMapper().startAddingDocuments("1");
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 100, "Storage A", 1000, 0, ""),
                 new MtpRoot(0, 101, "Storage B", 1001, 0, "")
         });
@@ -273,63 +282,40 @@
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(100, getInt(cursor, COLUMN_STORAGE_ID));
             assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
             cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(101, getInt(cursor, COLUMN_STORAGE_ID));
             assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
             cursor.close();
         }
 
+        // Clear mapping and add a device.
         mDatabase.getMapper().clearMapping();
+        addTestDevice();
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
-            assertEquals(2, cursor.getCount());
-            cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_STORAGE_ID));
-            assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
-            cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_STORAGE_ID));
-            assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
+            assertEquals(0, cursor.getCount());
             cursor.close();
         }
 
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+        // Add two storages, but one's name is different from previous one.
+        mDatabase.getMapper().startAddingDocuments("1");
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 200, "Storage A", 2000, 0, ""),
                 new MtpRoot(0, 202, "Storage C", 2002, 0, "")
         });
+        mDatabase.getMapper().stopAddingDocuments("1");
 
         {
-            final Cursor cursor = mDatabase.queryRootDocuments(columns);
-            assertEquals(3, cursor.getCount());
-            cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_STORAGE_ID));
-            assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
-            cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_STORAGE_ID));
-            assertEquals("Storage B", getString(cursor, COLUMN_DISPLAY_NAME));
-            cursor.moveToNext();
-            assertEquals(4, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertEquals(202, getInt(cursor, COLUMN_STORAGE_ID));
-            assertEquals("Storage C", getString(cursor, COLUMN_DISPLAY_NAME));
-            cursor.close();
-        }
-
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
-
-        {
+            // After compeleting mapping, Storage A can be obtained with new storage ID.
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
             cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
             assertEquals("Storage A", getString(cursor, COLUMN_DISPLAY_NAME));
             cursor.moveToNext();
@@ -346,69 +332,49 @@
                 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE,
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
-        mDatabase.getMapper().startAddingDocuments("parentId");
-        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+
+        addTestDevice();
+        addTestStorage("1");
+
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", 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)
         });
         mDatabase.getMapper().clearMapping();
 
+        addTestDevice();
+        addTestStorage("1");
+
         {
-            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
-            assertEquals(3, cursor.getCount());
-
-            cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
-            assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));
-
-            cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
-            assertEquals("image.jpg", getString(cursor, COLUMN_DISPLAY_NAME));
-
-            cursor.moveToNext();
-            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
-            assertEquals("music.mp3", getString(cursor, COLUMN_DISPLAY_NAME));
-
+            // Don't return objects that lost MTP object handles.
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
+            assertEquals(0, cursor.getCount());
             cursor.close();
         }
 
-        mDatabase.getMapper().startAddingDocuments("parentId");
-        mDatabase.getMapper().putChildDocuments(0, "parentId", new MtpObjectInfo[] {
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
                 createDocument(203, "video.mp4", MtpConstants.FORMAT_MP4_CONTAINER, 1024),
         });
+        mDatabase.getMapper().stopAddingDocuments("2");
 
         {
-            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
-            assertEquals(4, cursor.getCount());
-
-            cursor.moveToPosition(3);
-            assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE));
-            assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME));
-
-            cursor.close();
-        }
-
-        mDatabase.getMapper().stopAddingDocuments("parentId");
-
-        {
-            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "2");
             assertEquals(2, cursor.getCount());
 
             cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
             assertEquals("note.txt", getString(cursor, COLUMN_DISPLAY_NAME));
 
             cursor.moveToNext();
-            assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(203, getInt(cursor, COLUMN_OBJECT_HANDLE));
             assertEquals("video.mp4", getString(cursor, COLUMN_DISPLAY_NAME));
+
             cursor.close();
         }
     }
@@ -424,10 +390,10 @@
                 Root.COLUMN_AVAILABLE_BYTES
         };
         mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device A", true, new MtpRoot[0], null, null));
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(1, "Device B", true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         mDatabase.getMapper().startAddingDocuments("1");
@@ -467,6 +433,13 @@
 
         mDatabase.getMapper().clearMapping();
 
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device A", "Device key A", true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                1, "Device B", "Device key B", true, new MtpRoot[0], null, null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
         mDatabase.getMapper().startAddingDocuments("1");
         mDatabase.getMapper().startAddingDocuments("2");
         mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
@@ -511,45 +484,71 @@
                 MtpDatabaseConstants.COLUMN_OBJECT_HANDLE
         };
 
-        mDatabase.getMapper().startAddingDocuments("parentId1");
-        mDatabase.getMapper().startAddingDocuments("parentId2");
-        mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+        // Add device, storage, and two directories.
+        addTestDevice();
+        addTestStorage("1");
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] {
+                createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
+                createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
+        });
+        mDatabase.getMapper().stopAddingDocuments("2");
+
+        // Put note.txt in each directory.
+        mDatabase.getMapper().startAddingDocuments("3");
+        mDatabase.getMapper().startAddingDocuments("4");
+        mDatabase.getMapper().putChildDocuments(0, "3", new MtpObjectInfo[] {
                 createDocument(100, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.getMapper().putChildDocuments(0, "4", new MtpObjectInfo[] {
                 createDocument(101, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
+
+        // Clear mapping.
         mDatabase.getMapper().clearMapping();
 
-        mDatabase.getMapper().startAddingDocuments("parentId1");
-        mDatabase.getMapper().startAddingDocuments("parentId2");
-        mDatabase.getMapper().putChildDocuments(0, "parentId1", new MtpObjectInfo[] {
+        // Add device, storage, and two directories again.
+        addTestDevice();
+        addTestStorage("1");
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(0, "2", new MtpObjectInfo[] {
+                createDocument(50, "A", MtpConstants.FORMAT_ASSOCIATION, 0),
+                createDocument(51, "B", MtpConstants.FORMAT_ASSOCIATION, 0),
+        });
+        mDatabase.getMapper().stopAddingDocuments("2");
+
+        // Add note.txt in each directory again.
+        mDatabase.getMapper().startAddingDocuments("3");
+        mDatabase.getMapper().startAddingDocuments("4");
+        mDatabase.getMapper().putChildDocuments(0, "3", new MtpObjectInfo[] {
                 createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.getMapper().putChildDocuments(0, "parentId2", new MtpObjectInfo[] {
+        mDatabase.getMapper().putChildDocuments(0, "4", new MtpObjectInfo[] {
                 createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
         });
-        mDatabase.getMapper().stopAddingDocuments("parentId1");
+        mDatabase.getMapper().stopAddingDocuments("3");
+        mDatabase.getMapper().stopAddingDocuments("4");
 
+        // Check if the two note.txt are mapped correctly.
         {
-            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId1");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "3");
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
-            assertEquals(1, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(5, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(200, getInt(cursor, COLUMN_OBJECT_HANDLE));
             cursor.close();
         }
         {
-            final Cursor cursor = mDatabase.queryChildDocuments(columns, "parentId2");
+            final Cursor cursor = mDatabase.queryChildDocuments(columns, "4");
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
-            assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
-            assertTrue(isNull(cursor, COLUMN_OBJECT_HANDLE));
+            assertEquals(6, getInt(cursor, COLUMN_DOCUMENT_ID));
+            assertEquals(201, getInt(cursor, COLUMN_OBJECT_HANDLE));
             cursor.close();
         }
     }
 
-    public void testClearMtpIdentifierBeforeResolveRootDocuments() {
+    public void testClearMtpIdentifierBeforeResolveRootDocuments() throws Exception {
         final String[] columns = new String[] {
                 DocumentsContract.Document.COLUMN_DOCUMENT_ID,
                 MtpDatabaseConstants.COLUMN_STORAGE_ID,
@@ -560,10 +559,7 @@
                 Root.COLUMN_AVAILABLE_BYTES
         };
 
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", false,  new MtpRoot[0], null, null));
-        mDatabase.getMapper().stopAddingDocuments(null);
+        addTestDevice();
 
         mDatabase.getMapper().startAddingDocuments("1");
         mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
@@ -571,12 +567,22 @@
         });
         mDatabase.getMapper().clearMapping();
 
+        addTestDevice();
+
+        try (final Cursor cursor = mDatabase.queryRoots(resources, rootColumns)) {
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("1", getString(cursor, Root.COLUMN_ROOT_ID));
+        }
+
         mDatabase.getMapper().startAddingDocuments("1");
         mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 200, "Storage", 2000, 0, ""),
         });
         mDatabase.getMapper().clearMapping();
 
+        addTestDevice();
+
         mDatabase.getMapper().startAddingDocuments("1");
         mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 300, "Storage", 3000, 0, ""),
@@ -609,39 +615,45 @@
                 DocumentsContract.Document.COLUMN_DISPLAY_NAME
         };
 
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
-                new MtpRoot(0, 100, "Storage", 0, 0, ""),
-        });
+        // Add a device and a storage.
+        addTestDevice();
+        addTestStorage("1");
+
+        // Disconnect devices.
         mDatabase.getMapper().clearMapping();
 
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+        // Add a device and two storages that has same name.
+        addTestDevice();
+        mDatabase.getMapper().startAddingDocuments("1");
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 200, "Storage", 2000, 0, ""),
                 new MtpRoot(0, 201, "Storage", 2001, 0, ""),
         });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
+        mDatabase.getMapper().stopAddingDocuments("1");
 
         {
             final Cursor cursor = mDatabase.queryRootDocuments(columns);
             assertEquals(2, cursor.getCount());
+
+            // First storage reuse document ID of previous storage.
             cursor.moveToNext();
+            // One reuses exisitng document ID 1.
             assertEquals(2, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(200, getInt(cursor, COLUMN_STORAGE_ID));
             assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
+
+            // Second one has new document ID.
             cursor.moveToNext();
             assertEquals(3, getInt(cursor, COLUMN_DOCUMENT_ID));
             assertEquals(201, getInt(cursor, COLUMN_STORAGE_ID));
             assertEquals("Storage", getString(cursor, COLUMN_DISPLAY_NAME));
+
             cursor.close();
         }
     }
 
-    public void testReplaceExistingRoots() {
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
-        mDatabase.getMapper().stopAddingDocuments(null);
+    public void testReplaceExistingRoots() throws Exception {
+        addTestDevice();
 
         // The client code should be able to replace existing rows with new information.
         // Add one.
@@ -686,67 +698,60 @@
         }
     }
 
-    public void testFailToReplaceExisitingUnmappedRoots() {
+    public void testFailToReplaceExisitingUnmappedRoots() throws Exception {
         // The client code should not be able to replace rows before resolving 'unmapped' rows.
         // Add one.
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", true, new MtpRoot[0], null, null));
-        mDatabase.getMapper().stopAddingDocuments(null);
-
+        addTestDevice();
         mDatabase.getMapper().startAddingDocuments("1");
         mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
         });
         mDatabase.getMapper().clearMapping();
-        final Cursor oldCursor = mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID));
-        assertEquals(1, oldCursor.getCount());
 
-        // Add one.
-        mDatabase.getMapper().startAddingDocuments("1");
-        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
-                new MtpRoot(0, 101, "Storage B", 1000, 1000, ""),
-        });
-        // Add one more before resolving unmapped documents.
-        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
-                new MtpRoot(0, 102, "Storage B", 1000, 1000, ""),
-        });
-        mDatabase.getMapper().stopAddingDocuments("1");
+        addTestDevice();
+        try (final Cursor oldCursor =
+                mDatabase.queryRoots(resources, strings(Root.COLUMN_ROOT_ID))) {
+            assertEquals(1, oldCursor.getCount());
+            oldCursor.moveToNext();
+            assertEquals("1", getString(oldCursor, Root.COLUMN_ROOT_ID));
 
-        // Because the roots shares the same name, the roots should have new IDs.
-        final Cursor newCursor = mDatabase.queryChildDocuments(
-                strings(Document.COLUMN_DOCUMENT_ID), "1");
-        assertEquals(2, newCursor.getCount());
-        oldCursor.moveToNext();
-        newCursor.moveToNext();
-        assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
-        newCursor.moveToNext();
-        assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
+            // Add one.
+            mDatabase.getMapper().startAddingDocuments("1");
+            mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
+                    new MtpRoot(0, 101, "Storage B", 1000, 1000, ""),
+            });
+            // Add one more before resolving unmapped documents.
+            mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
+                    new MtpRoot(0, 102, "Storage B", 1000, 1000, ""),
+            });
+            mDatabase.getMapper().stopAddingDocuments("1");
 
-        oldCursor.close();
-        newCursor.close();
+            // Because the roots shares the same name, the roots should have new IDs.
+            try (final Cursor newCursor = mDatabase.queryChildDocuments(
+                    strings(Document.COLUMN_DOCUMENT_ID), "1")) {
+                assertEquals(2, newCursor.getCount());
+                newCursor.moveToNext();
+                assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
+                newCursor.moveToNext();
+                assertFalse(oldCursor.getString(0).equals(newCursor.getString(0)));
+            }
+        }
     }
 
-    public void testQueryDocuments() {
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
-                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
-        });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
+    public void testQueryDocuments() throws Exception {
+        addTestDevice();
+        addTestStorage("1");
 
-        final Cursor cursor = mDatabase.queryDocument("1", strings(Document.COLUMN_DISPLAY_NAME));
+        final Cursor cursor = mDatabase.queryDocument("2", strings(Document.COLUMN_DISPLAY_NAME));
         assertEquals(1, cursor.getCount());
         cursor.moveToNext();
-        assertEquals("Storage A", getString(cursor, Document.COLUMN_DISPLAY_NAME));
+        assertEquals("Storage", getString(cursor, Document.COLUMN_DISPLAY_NAME));
         cursor.close();
     }
 
-    public void testQueryRoots() {
+    public void testQueryRoots() throws Exception {
         // Add device document.
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(0, "Device", false, new MtpRoot[0], null, null));
-        mDatabase.getMapper().stopAddingDocuments(null);
+        addTestDevice();
 
         // It the device does not have storages, it shows a device root.
         {
@@ -790,38 +795,12 @@
     }
 
     public void testGetParentId() throws FileNotFoundException {
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
-                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
-        });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
+        addTestDevice();
 
         mDatabase.getMapper().startAddingDocuments("1");
-        mDatabase.getMapper().putChildDocuments(
-                0,
-                "1",
-                new MtpObjectInfo[] {
-                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
-                });
-        mDatabase.getMapper().stopAddingDocuments("1");
-
-        assertEquals("1", mDatabase.getParentIdentifier("2").mDocumentId);
-    }
-
-    public void testDeleteDocument() {
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
+        mDatabase.getMapper().putStorageDocuments("1", new MtpRoot[] {
                 new MtpRoot(0, 100, "Storage A", 0, 0, ""),
         });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
-
-        mDatabase.getMapper().startAddingDocuments("1");
-        mDatabase.getMapper().putChildDocuments(
-                0,
-                "1",
-                new MtpObjectInfo[] {
-                        createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
-                });
         mDatabase.getMapper().stopAddingDocuments("1");
 
         mDatabase.getMapper().startAddingDocuments("2");
@@ -833,12 +812,37 @@
                 });
         mDatabase.getMapper().stopAddingDocuments("2");
 
-        mDatabase.deleteDocument("2");
+        assertEquals("2", mDatabase.getParentIdentifier("3").mDocumentId);
+    }
+
+    public void testDeleteDocument() throws Exception {
+        addTestDevice();
+        addTestStorage("1");
+
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.getMapper().putChildDocuments(
+                0,
+                "2",
+                new MtpObjectInfo[] {
+                        createDocument(200, "dir", MtpConstants.FORMAT_ASSOCIATION, 1024),
+                });
+        mDatabase.getMapper().stopAddingDocuments("2");
+
+        mDatabase.getMapper().startAddingDocuments("3");
+        mDatabase.getMapper().putChildDocuments(
+                0,
+                "3",
+                new MtpObjectInfo[] {
+                        createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024),
+                });
+        mDatabase.getMapper().stopAddingDocuments("3");
+
+        mDatabase.deleteDocument("3");
 
         {
             // Do not query deleted documents.
             final Cursor cursor =
-                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
             assertEquals(0, cursor.getCount());
             cursor.close();
         }
@@ -846,64 +850,62 @@
         {
             // Child document should be deleted also.
             final Cursor cursor =
-                    mDatabase.queryDocument("3", strings(Document.COLUMN_DOCUMENT_ID));
+                    mDatabase.queryDocument("4", strings(Document.COLUMN_DOCUMENT_ID));
             assertEquals(0, cursor.getCount());
             cursor.close();
         }
     }
 
-    public void testPutNewDocument() {
-        mDatabase.getMapper().startAddingDocuments("deviceDocId");
-        mDatabase.getMapper().putStorageDocuments("deviceDocId", new MtpRoot[] {
-                new MtpRoot(0, 100, "Storage A", 0, 0, ""),
-        });
-        mDatabase.getMapper().stopAddingDocuments("deviceDocId");
+    public void testPutNewDocument() throws Exception {
+        addTestDevice();
+        addTestStorage("1");
 
         assertEquals(
-                "2",
+                "3",
                 mDatabase.putNewDocument(
-                        0, "1", createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
+                        0, "2", createDocument(200, "note.txt", MtpConstants.FORMAT_TEXT, 1024)));
 
         {
             final Cursor cursor =
-                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
-            assertEquals(1, cursor.getCount());
-            cursor.moveToNext();
-            assertEquals("2", cursor.getString(0));
-            cursor.close();
-        }
-
-        // The new document should not be mapped with existing invalidated document.
-        mDatabase.getMapper().clearMapping();
-        mDatabase.getMapper().startAddingDocuments("1");
-        mDatabase.putNewDocument(
-                0,
-                "1",
-                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
-        mDatabase.getMapper().stopAddingDocuments("1");
-
-        {
-            final Cursor cursor =
-                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "1");
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
             assertEquals(1, cursor.getCount());
             cursor.moveToNext();
             assertEquals("3", cursor.getString(0));
             cursor.close();
         }
+
+        // The new document should not be mapped with existing invalidated document.
+        mDatabase.getMapper().clearMapping();
+        addTestDevice();
+        addTestStorage("1");
+
+        mDatabase.getMapper().startAddingDocuments("2");
+        mDatabase.putNewDocument(
+                0,
+                "2",
+                createDocument(201, "note.txt", MtpConstants.FORMAT_TEXT, 1024));
+        mDatabase.getMapper().stopAddingDocuments("2");
+
+        {
+            final Cursor cursor =
+                    mDatabase.queryChildDocuments(strings(Document.COLUMN_DOCUMENT_ID), "2");
+            assertEquals(1, cursor.getCount());
+            cursor.moveToNext();
+            assertEquals("4", cursor.getString(0));
+            cursor.close();
+        }
     }
 
-    public void testGetDocumentIdForDevice() {
-        mDatabase.getMapper().startAddingDocuments(null);
-        mDatabase.getMapper().putDeviceDocument(
-                new MtpDeviceRecord(100, "Device", true, new MtpRoot[0], null, null));
-        mDatabase.getMapper().stopAddingDocuments(null);
-        assertEquals("1", mDatabase.getDocumentIdForDevice(100));
+    public void testGetDocumentIdForDevice() throws Exception {
+        addTestDevice();
+        assertEquals("1", mDatabase.getDocumentIdForDevice(0));
     }
 
-    public void testGetClosedDevice() {
+    public void testGetClosedDevice() throws Exception {
         mDatabase.getMapper().startAddingDocuments(null);
         mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
-                0, "Device", /* opened is */ false , new MtpRoot[0], null, null));
+                0, "Device", null /* deviceKey */, /* opened is */ false, new MtpRoot[0], null,
+                null));
         mDatabase.getMapper().stopAddingDocuments(null);
 
         final String[] columns = new String [] {
@@ -919,4 +921,80 @@
             assertTrue(cursor.isNull(2));
         }
     }
+
+    public void testMappingWithoutKey() throws FileNotFoundException {
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
+                null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
+                null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        try (final Cursor cursor =
+                mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
+            assertEquals(1, cursor.getCount());
+            assertTrue(cursor.moveToNext());
+            assertEquals(1, cursor.getLong(0));
+        }
+    }
+
+    public void testMappingFailsWithoutKey() throws FileNotFoundException {
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
+                null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        // MTP identifier is cleared here. Mapping no longer works without device key.
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", null /* device key */, /* opened is */ true, new MtpRoot[0], null,
+                null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+
+        try (final Cursor cursor =
+                mDatabase.queryRoots(resources, strings(DocumentsContract.Root.COLUMN_ROOT_ID))) {
+            assertEquals(1, cursor.getCount());
+            assertTrue(cursor.moveToNext());
+            assertEquals(2, cursor.getLong(0));
+        }
+    }
+
+    public void testUpdateDocumentWithoutChange() throws FileNotFoundException {
+        mDatabase.getMapper().startAddingDocuments(null);
+        assertTrue(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
+                null)));
+        assertFalse(mDatabase.getMapper().stopAddingDocuments(null));
+
+        mDatabase.getMapper().startAddingDocuments(null);
+        assertFalse(mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
+                null)));
+        assertFalse(mDatabase.getMapper().stopAddingDocuments(null));
+    }
+
+    private void addTestDevice() throws FileNotFoundException {
+        mDatabase.getMapper().startAddingDocuments(null);
+        mDatabase.getMapper().putDeviceDocument(new MtpDeviceRecord(
+                0, "Device", "device_key", /* opened is */ true, new MtpRoot[0], null,
+                null));
+        mDatabase.getMapper().stopAddingDocuments(null);
+    }
+
+    private void addTestStorage(String parentId) throws FileNotFoundException {
+        mDatabase.getMapper().startAddingDocuments(parentId);
+        mDatabase.getMapper().putStorageDocuments(parentId, new MtpRoot[] {
+                new MtpRoot(0, 100, "Storage", 1024, 1024, ""),
+        });
+        mDatabase.getMapper().stopAddingDocuments(parentId);
+    }
 }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index 5b0f557..5eda9b2 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -29,6 +29,8 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import com.android.mtp.exceptions.BusyDeviceException;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
@@ -63,6 +65,7 @@
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 0,
                 "Device A",
+                null /* deviceKey */,
                 false /* unopened */,
                 new MtpRoot[] {
                     new MtpRoot(
@@ -100,6 +103,7 @@
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 0,
                 "Device A",
+                null /* deviceKey */,
                 false /* unopened */,
                 new MtpRoot[] {
                     new MtpRoot(
@@ -123,6 +127,7 @@
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 0,
                 "Device A",
+                null /* deviceKey */,
                 false /* unopened */,
                 new MtpRoot[] {
                     new MtpRoot(
@@ -167,6 +172,7 @@
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 0,
                 "Device A",
+                "Device key A",
                 false /* unopened */,
                 new MtpRoot[] {
                         new MtpRoot(
@@ -182,6 +188,7 @@
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 1,
                 "Device B",
+                "Device key B",
                 false /* unopened */,
                 new MtpRoot[] {
                     new MtpRoot(
@@ -228,10 +235,17 @@
     public void testQueryRoots_error() throws Exception {
         setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
         mMtpManager.addValidDevice(new MtpDeviceRecord(
-                0, "Device A", false /* unopened */, new MtpRoot[0], null, null));
+                0,
+                "Device A",
+                "Device key A",
+                false /* unopened */,
+                new MtpRoot[0],
+                null,
+                null));
         mMtpManager.addValidDevice(new MtpDeviceRecord(
                 1,
                 "Device B",
+                "Device key B",
                 false /* unopened */,
                 new MtpRoot[] {
                     new MtpRoot(
@@ -526,6 +540,53 @@
         }
     }
 
+    public void testBusyDevice() throws Exception {
+        mMtpManager = new TestMtpManager(getContext()) {
+            @Override
+            void openDevice(int deviceId) throws IOException {
+                throw new BusyDeviceException();
+            }
+        };
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        mMtpManager.addValidDevice(new MtpDeviceRecord(
+                0, "Device A", null /* deviceKey */, false /* unopened */, new MtpRoot[0], null,
+                null));
+
+        mProvider.resumeRootScanner();
+        mResolver.waitForNotification(ROOTS_URI, 1);
+
+        try (final Cursor cursor = mProvider.queryRoots(null)) {
+            assertEquals(1, cursor.getCount());
+        }
+
+        try (final Cursor cursor = mProvider.queryChildDocuments("1", null, null)) {
+            assertEquals(0, cursor.getCount());
+            assertEquals(
+                    "error_busy_device",
+                    cursor.getExtras().getString(DocumentsContract.EXTRA_ERROR));
+        }
+    }
+
+    public void testLockedDevice() throws Exception {
+        setupProvider(MtpDatabaseConstants.FLAG_DATABASE_IN_MEMORY);
+        mMtpManager.addValidDevice(new MtpDeviceRecord(
+                0, "Device A", null, false /* unopened */, new MtpRoot[0], null, null));
+
+        mProvider.resumeRootScanner();
+        mResolver.waitForNotification(ROOTS_URI, 1);
+
+        try (final Cursor cursor = mProvider.queryRoots(null)) {
+            assertEquals(1, cursor.getCount());
+        }
+
+        try (final Cursor cursor = mProvider.queryChildDocuments("1", null, null)) {
+            assertEquals(0, cursor.getCount());
+            assertEquals(
+                    "error_locked_device",
+                    cursor.getExtras().getString(DocumentsContract.EXTRA_ERROR));
+        }
+    }
+
     private void setupProvider(int flag) {
         mDatabase = new MtpDatabase(getContext(), flag);
         mProvider = new MtpDocumentsProvider();
@@ -555,7 +616,8 @@
             throws InterruptedException, TimeoutException, IOException {
         final int changeCount = mResolver.getChangeCount(ROOTS_URI);
         mMtpManager.addValidDevice(
-                new MtpDeviceRecord(deviceId, "Device", false /* unopened */, roots, null, null));
+                new MtpDeviceRecord(deviceId, "Device", null /* deviceKey */, false /* unopened */,
+                roots, null, null));
         mProvider.openDevice(deviceId);
         mResolver.waitForNotification(ROOTS_URI, changeCount + 1);
         return getStrings(mProvider.queryRoots(strings(DocumentsContract.Root.COLUMN_ROOT_ID)));
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
index 9ebe4d1..2e172b1 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpManagerTest.java
@@ -94,6 +94,13 @@
         getInstrumentation().show(Arrays.toString(records[0].eventsSupported));
     }
 
+    public void testDeviceKey() {
+        final MtpDeviceRecord[] records = mManager.getDevices();
+        assertEquals(1, records.length);
+        assertNotNull(records[0].deviceKey);
+        getInstrumentation().show("deviceKey: " + records[0].deviceKey);
+    }
+
     public void testEventObjectAdded() throws Exception {
         while (true) {
             getInstrumentation().show("Please take a photo by using connected MTP device.");
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
index 1aaeb60..4378152 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestMtpManager.java
@@ -76,7 +76,8 @@
                 result[i] = device;
             } else {
                 result[i] = new MtpDeviceRecord(
-                        device.deviceId, device.name, device.opened, new MtpRoot[0], null, null);
+                        device.deviceId, device.name, device.deviceKey, device.opened,
+                        new MtpRoot[0], null, null);
             }
         }
         return result;
@@ -90,7 +91,9 @@
         }
         mDevices.put(
                 deviceId,
-                new MtpDeviceRecord(device.deviceId, device.name, true, device.roots, null, null));
+                new MtpDeviceRecord(
+                        device.deviceId, device.name, device.deviceKey, true, device.roots, null,
+                        null));
     }
 
     @Override
@@ -101,7 +104,8 @@
         }
         mDevices.put(
                 deviceId,
-                new MtpDeviceRecord(device.deviceId, device.name, false, device.roots, null, null));
+                new MtpDeviceRecord(device.deviceId, device.name, device.deviceKey, false,
+                        device.roots, null, null));
     }
 
     @Override
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
index b23038b..8676b5a 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/TestResources.java
@@ -24,6 +24,10 @@
         switch (id) {
             case R.string.root_name:
                 return "%1$s %2$s";
+            case R.string.error_busy_device:
+                return "error_busy_device";
+            case R.string.error_locked_device:
+                return "error_locked_device";
         }
         throw new NotFoundException();
     }
diff --git a/packages/SettingsLib/res/layout/usage_bottom_label.xml b/packages/SettingsLib/res/layout/usage_bottom_label.xml
new file mode 100644
index 0000000..6c16880
--- /dev/null
+++ b/packages/SettingsLib/res/layout/usage_bottom_label.xml
@@ -0,0 +1,20 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_side_label.xml b/packages/SettingsLib/res/layout/usage_side_label.xml
new file mode 100644
index 0000000..6c16880
--- /dev/null
+++ b/packages/SettingsLib/res/layout/usage_side_label.xml
@@ -0,0 +1,20 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml
new file mode 100644
index 0000000..28981f8
--- /dev/null
+++ b/packages/SettingsLib/res/layout/usage_view.xml
@@ -0,0 +1,87 @@
+<!--
+    Copyright (C) 2016 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/graph_label_group"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/usage_graph_area_height"
+        android:orientation="horizontal"
+        android:clipChildren="false"
+        android:clipToPadding="false">
+
+        <LinearLayout
+            android:id="@+id/label_group"
+            android:layout_width="@dimen/usage_graph_labels_width"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+
+            <include android:id="@+id/label_top"
+                layout="@layout/usage_side_label" />
+
+            <Space
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+
+            <include android:id="@+id/label_middle"
+                layout="@layout/usage_side_label" />
+
+            <Space
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+
+            <include android:id="@+id/label_bottom"
+                layout="@layout/usage_side_label" />
+
+        </LinearLayout>
+
+        <com.android.settingslib.graph.UsageGraph
+            android:id="@+id/usage_graph"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1"
+            android:layout_marginTop="@dimen/usage_graph_margin_top_bottom"
+            android:layout_marginBottom="@dimen/usage_graph_margin_top_bottom" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/bottom_label_group"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="@dimen/usage_graph_labels_width"
+        android:orientation="horizontal">
+
+        <include android:id="@+id/label_start"
+            layout="@layout/usage_side_label" />
+
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1" />
+
+        <include android:id="@+id/label_end"
+            layout="@layout/usage_side_label" />
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 49d9f17..2ddb1e9 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Laat altyd Wi-Fi-swerfskanderings toe"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Gebruik vorige DHCP-kliënt"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Sellulêre data altyd aktief"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiveer absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Wys opsies vir draadlose skermsertifisering"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Verhoog Wi-Fi-aantekeningvlak, wys per SSID RSSI in Wi‑Fi-kieser"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Wanneer dit geaktiveer is, sal Wi-Fi meer aggressief wees om die dataverbinding na selfoon oor te dra wanneer die Wi-Fi-sein swak is"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Hierdie instellings is bedoel net vir ontwikkelinggebruik. Dit kan jou toestel en die programme daarop breek of vreemde dinge laat doen."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifieer programme oor USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontroleer programme wat via ADB/ADT geïnstalleer is vir skadelike gedrag."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Deaktiveer die Bluetooth-kenmerk vir absolute volume indien daar volumeprobleme met afgeleë toestelle is, soos onaanvaarbare harde klank of geen beheer nie."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Plaaslike terminaal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktiveer terminaalprogram wat plaaslike skermtoegang bied"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-kontrolering"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Flits skerm as programme lang handelinge doen op die hoofdraad"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Wyserligging"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Skermlaag wys huidige raakdata"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Wys tikke"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Wys visuele terugvoer vir tikke"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Wys oppervlakopdaterings"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Flits vensteroppervlaktes in geheel wanneer dit opdateer"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Wys GPU-aansigopdaterings"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiveer steun vir eksperimentele vormvrye-Windows."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Werkskerm-rugsteunwagwoord"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Volle rekenaarrugsteune word nie tans beskerm nie"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tik om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nuwe rugsteunwagwoord ingestel"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nuwe wagwoord en bevestiging stem nie ooreen nie"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Rugsteunwagwoord kon nie ingestel word nie"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Kleure vir digitale inhoud geoptimeer"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Onaktiewe programme"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Onaktief. Tik om te wissel."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktief. Tik om te wissel."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Lopende dienste"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Sien en beheer dienste wat tans loop"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Nagmodus"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurregstelling"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – sowat <xliff:g id="TIME">%2$s</xliff:g> oor"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Gedeaktiveer deur administrateur"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Tuis"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index ab3d304..4276bea 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ሁልጊዜ የWi‑Fi ማንቀሳቀስ ቅኝቶችን ይፍቀዱ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"የቆየ የDHCP ደንበኛ ይጠቀሙ"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"የተንቀስቃሽ ስልክ ውሂብ ሁልጊዜ ንቁ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ፍጹማዊ ድምፅን አሰናክል"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"የገመድ አልባ ማሳያ እውቅና ማረጋገጫ አማራጮችን አሳይ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"የWi‑Fi ምዝግብ ማስታወሻ አያያዝ ደረጃ ጨምር፣ በWi‑Fi መምረጫ ውስጥ በአንድ SSID RSSI አሳይ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ሲነቃ የWi‑Fi ምልክት ዝቅተኛ ሲሆን Wi‑Fi የውሂብ ግንኙነት ለተንቀሳቃሽ ማስረከብ ላይ ይበልጥ አስገዳጅ ይሆናል"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"እነዚህ ቅንብሮች  የታሰቡት ለግንባታ አጠቃቀም ብቻ ናቸው። መሳሪያህን እና በሱ ላይ ያሉትን መተግበሪያዎች እንዲበለሹ ወይም በትክክል እንዳይሰሩ ሊያደርጉ ይችላሉ።"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"መተግበሪያዎች በUSB በኩል ያረጋግጡ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"በADB/ADT በኩል የተጫኑ መተግበሪያዎች ጎጂ ባህሪ ካላቸው ያረጋግጡ።"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"እንደ ተቀባይነት በሌለው ደረጃ ድምፁ ከፍ ማለት ወይም መቆጣጠር አለመቻል ያሉ ከሩቅ መሣሪያዎች ጋር የድምፅ ችግር በሚኖርበት ጊዜ የብሉቱዝ ፍጹማዊ ድምፅን ባሕሪ ያሰናክላል።"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"አካባቢያዊ ተርሚናል"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"የአካባቢያዊ ሼል መዳረሻ የሚያቀርብ የተርሚናል መተግበሪያ አንቃ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"የHDCP ምልከታ"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"የቀለም ማስተካከያ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ገደማ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> እስከሚሞላ ድረስ"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል  እየሞላ አይደለም"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"በአስተዳዳሪ የተሰናከለ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"መነሻ"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 12d3323..67fb59c 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏السماح دائمًا بعمليات فحص Wi-Fi للتجوال"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"‏استخدام برنامج DHCP القديم"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"بيانات الجوّال نشطة دائمًا"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"تعطيل مستوى الصوت المطلق"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"عرض خيارات شهادة عرض شاشة لاسلكي"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏زيادة مستوى تسجيل Wi-Fi، وعرض لكل SSID RSSI في منتقي Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"‏عند تمكينه، سيكون Wi-Fi أكثر حدة في تسليم اتصال البيانات إلى الشبكة الخلوية، وذلك عندما تكون إشارة WiFi منخفضة"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"هذه الإعدادات مخصصة لاستخدام التطوير فقط. قد يتسبب هذا في حدوث أعطال أو خلل في أداء الجهاز والتطبيقات المثبتة عليه."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"‏التحقق من التطبيقات عبر USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"‏التحقق من التطبيقات المثبتة عبر ADB/ADT لكشف السلوك الضار"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"لتعطيل ميزة مستوى الصوت المطلق للبلوتوث في حالة حدوث مشكلات متعلقة بمستوى الصوت مع الأجهزة البعيدة مثل مستوى صوت عالٍ بشكل غير مقبول أو نقص إمكانية التحكم في الصوت."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"تطبيق طرفي محلي"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"تمكين تطبيق طرفي يوفر إمكانية الدخول إلى واجهة النظام المحلية"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"‏التحقق من HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"وميض الشاشة عند إجراء التطبيقات عمليات طويلة في سلسلة المحادثات الرئيسية"</string>
     <string name="pointer_location" msgid="6084434787496938001">"موقع المؤشر"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"عرض تراكب الشاشة لبيانات اللمس الحالية"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"عرض النقرات"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"عرض التعليقات المرئية للنقرات"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"عرض تحديثات السطح"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"وميض أسطح النوافذ بالكامل عندما يتم تحديثها"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"‏إظهار تحديثات عرض GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"لتمكين إتاحة استخدام النوافذ الحرة التجريبية."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"كلمة مرور احتياطية للكمبيوتر"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"النسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"تم تعيين كلمة مرور احتياطية جديدة"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"كلمة المرور الجديدة وتأكيدها لا يتطابقان"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"أخفق تعيين كلمة مرور احتياطية"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"الألوان المحسَّنة للمحتوى الرقمي"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"التطبيقات غير النشطة"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"غير نشط، انقر للتبديل."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"نشط، انقر للتبديل."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"الخدمات قيد التشغيل"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"عرض الخدمات قيد التشغيل في الوقت الحالي والتحكم فيها"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"الوضع الليلي"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحيح الألوان"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"تم التعطيل بواسطة المشرف"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"الشاشة الرئيسية"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml
index 6c6903e..12b077e 100644
--- a/packages/SettingsLib/res/values-az-rAZ/strings.xml
+++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi axtarışlarına həmişə icazə verin"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Köhnə DHCP klient istifadə edin"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobil data həmişə aktivdir"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mütləq səs həcmi deaktiv edin"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz displey sertifikatlaşması üçün seçimləri göstərir"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi giriş səviyyəsini qaldırın, Wi‑Fi seçəndə hər SSID RSSI üzrə göstərin"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Aktiv olanda, Wi‑Fi sianqlı zəif olan zaman, Mobil şəbəkə data bağlantısına nisbətən, Wi‑Fi daha aqressiv olacaq"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Bu parametrlər yalnız inkişafetdirici istifadə üçün nəzərdə tutulub. Onlar cihaz və tətbiqlərinizin sınması və ya pis işləməsinə səbəb ola bilər."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB üzərindən tətbiqləri yoxlayın"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT vasitəsi ilə quraşdırılmış tətbiqləri zərərli davranış üzrə yoxlayın."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Uzaqdan idarə olunan cihazlarda dözülməz yüksək səs həcmi və ya nəzarət çatışmazlığı kimi səs problemləri olduqda Bluetooth mütləq səs həcmi xüsusiyyətini deaktiv edir."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Yerli terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Yerli örtük girişini təklif edən terminal tətbiqi aktiv edin"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP yoxlanılır"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rəng düzəlişi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> dolana qədər"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administrator tərəfindən deaktiv edildi"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Əsas səhifə"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> əvvəl"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> qalıb"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 669b92d..ae56978 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvek dozvoli skeniranje Wi‑Fi-ja u romingu"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Koristi zastareli DHCP klijent"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Podaci za mobilne uređaje su uvek aktivni"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući glavno podešavanje jačine zvuka"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaz opcija za sertifikaciju bežičnog ekrana"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećava nivo evidentiranja za Wi‑Fi. Prikaz po SSID RSSI-u u biraču Wi‑Fi mreže"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kada se omogući, Wi‑Fi će biti agresivniji pri prebacivanju mreže za prenos podataka na Mobilnu, kada je Wi‑Fi signal slab"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ova podešavanja su namenjena samo za programiranje. Mogu da izazovu prestanak funkcionisanja ili neočekivano ponašanje uređaja i aplikacija na njemu."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije preko USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Proverava da li su aplikacije instalirane preko ADB-a/ADT-a štetne."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava glavno podešavanje jačine zvuka na Bluetooth uređaju u slučaju problema sa jačinom zvuka na daljinskim uređajima, kao što su izuzetno velika jačina zvuka ili nedostatak kontrole."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući aplik. terminala za pristup lokalnom komandnom okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provera"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Neka ekran treperi kada aplikacije obavljaju duge operacije na glavnoj niti"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Lokacija pokazivača"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Postav. element sa trenutnim podacima o dodiru"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Prikazuj dodire"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Prikazuj vizuelne povratne informacije za dodire"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Prikaži ažuriranja površine"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Osvetli sve površine prozora kada se ažuriraju"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Prikaži ažur. GPU prikaza"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka rezervne kopije za računar"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Postavljena je nova lozinka rezervne kopije"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nova lozinka i njena potvrda se ne podudaraju"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Postavljanje lozinke rezervne kopije nije uspelo"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Boje optimizovane za digitalni sadržaj"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Neaktivne aplikacije"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Neaktivna. Dodirnite da biste je aktivirali."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivna. Dodirnite da biste je deaktivirali."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Noćni režim"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boja"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo oko <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogućio je administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Početni"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index a87e3d5..ad0ace4 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Сканирането за роуминг на Wi-Fi да е разрешено винаги"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Наследена клиентска програма за DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Винаги активни клетъчни данни"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Деактивиране на пълната сила на звука"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показване на опциите за сертифициране на безжичния дисплей"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"По-подробно регистр. на Wi‑Fi – данни за RSSI на SSID в инстр. за избор на Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"При активиране предаването на връзката за данни от Wi-Fi към мобилната мрежа ще е по-агресивно, когато Wi-Fi сигналът е слаб"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Тези настройки са предназначени само за програмиране. Те могат да доведат до прекъсване на работата или неправилно функциониране на устройството ви и приложенията в него."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Потвържд. на прил. през USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Проверка на инсталираните чрез ADB/ADT приложения за опасно поведение."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Деактивира функцията на Bluetooth за пълна сила на звука в случай на проблеми със звука на отдалечени устройства, като например неприемливо висока сила на звука или липса на управление."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локален терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Актив. на прил. за терминал с достъп до локалния команден ред"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Проверка с HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Примигване на екрана при дълги операции в главната нишка"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Mестопол. на показалеца"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Насл. на екран показва текущи данни при докосване"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Показване на докосванията"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Показване на визуална обр. връзка за докосванията"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Актуал. на повърхн: Показв."</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Примигв. на целите повърхности на прозорците при актуализирането им"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Показв. на актуал. на изгледа от GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Активира поддръжката за експерименталните прозорци в свободна форма."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Наст. комп.: Парола"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Понастоящем пълните резервни копия за настолен компютър не са защитени"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Докоснете, за да промените или премахнете паролата за пълни резервни копия на настолния компютър"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Зададена е нова парола за резервно копие"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Новата парола и въведената за потвърждаване не съвпадат"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Задаването на парола за резервно копие не бе успешно"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Цветове, оптимизирани за дигитално съдържание"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Неактивни приложения"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Неактивно. Докоснете, за да превключите."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Активно. Докоснете, за да превключите."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Изпълнявани услуги:"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Преглед и контрол върху изпълняващите се понастоящем услуги"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Нощен режим"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекция на цветове"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – приблизително оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Деактивирано от администратора"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Начало"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml
index 82d70b9..589c52e 100644
--- a/packages/SettingsLib/res/values-bn-rBD/strings.xml
+++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"সর্বদা Wifi রোম স্ক্যানকে অনুমতি দিন"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"লেগাসি DHCP ক্লায়েন্ট ব্যবহার করুন"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"সেলুলার ডেটা সর্বদাই সক্রিয় থাকে"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"চূড়ান্ত ভলিউম অক্ষম করুন"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ওয়্যারলেস প্রদর্শন সার্টিফিকেশন জন্য বিকল্পগুলি দেখান"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi লগিং স্তর বাড়ান, Wi‑Fi চয়নকারীতে SSID RSSI অনুযায়ী দেখান"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"সক্ষম করা থাকলে, নিম্নমানের Wi‑Fi সিগন্যালের ক্ষেত্রে, সেলুলার-এ ডেটা সংযোগ প্রদান করতে Wi‑Fi আরো বেশি শক্তিশালীভাবে কাজ করবে"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"এইসব সেটিংস কেবলমাত্র উন্নত করার উদ্দেশ্য। সেগুলি কারণে আপনার ডিভাইস ভেঙ্গে এবং অ্যাপ্লিকেশানগুলি ভালো ভাবে কাজ করা নাও কারতে পারে।"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB এর অ্যাপ্লিকেশানগুলি যাচাই করুন"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ক্ষতিকারক ক্রিয়াকলাপ করছে কিনা তার জন্য ADB/ADT মারফত ইনস্টল করা অ্যাপ্লিকেশানগুলি চেক করুন।"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"অপ্রত্যাশিত উচ্চ ভলিউম বা নিয়ন্ত্রণের অভাবের মত দূরবর্তী ডিভাইসের ভলিউম সমস্যাগুলির ক্ষেত্রে, Bluetooth চুড়ান্ত ভলিউম বৈশিষ্ট্য অক্ষম করে৷"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"স্থানীয় টার্মিনাল"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"স্থানীয় শেল অ্যাক্সেসের প্রস্তাব করে এমন টার্মিনাল অ্যাপ্লিকেশন সক্ষম করুন"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP পরীক্ষণ"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"মুখ্য থ্রেডে অ্যাপ্লিকেশানগুলির দীর্ঘ কার্যকলাপের সময় স্ক্রীন ফ্ল্যাশ করে"</string>
     <string name="pointer_location" msgid="6084434787496938001">"পয়েন্টারের অবস্থান"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"স্ক্রীন ওভারলে বর্তমান স্পর্শ ডেটা দেখাচ্ছে"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"আলতো চাপ দেখান"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"আলতো চাপ দিলে ভিজ্যুয়াল প্রতিক্রিয়া দেখান"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"সারফেস আপডেটগুলি দেখান"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"সম্পূর্ণ উইন্ডোর সারফেস আপডেট হয়ে গেলে সেটিকে ফ্ল্যাশ করুন"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU দৃশ্য আপডেটগুলি প্রদর্শন করুন"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ডেস্কটপ ব্যাকআপ পাসওয়ার্ড"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ডেস্কটপ পূর্ণ ব্যাকআপ বর্তমানে সুরক্ষিত নয়"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ডেস্কটপের সম্পূর্ণ ব্যাকআপের পাসওয়ার্ডটি পরিবর্তন করতে বা মুছে ফেলতে আলতো চাপুন"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"নতুন ব্যাকআপ পাসওয়ার্ড সেট করুন"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"নতুন পাসওয়ার্ড এবং নিশ্চিতকরণ মিলছে না"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ব্যাকআপ পাসওয়ার্ড সেট করা ব্যর্থ"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"ডিজিট্যাল সামগ্রীর জন্য অপ্টিমাইজ করা রঙগুলি"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"নিষ্ক্রিয় অ্যাপ্লিকেশানগুলি"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"নিষ্ক্রিয় রয়েছে৷ টগল করতে আলতো চাপুন৷"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"সক্রিয় রয়েছে৷ টগল করতে আলতো চাপুন৷"</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"এখন চলছে যে পরিষেবাগুলি"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"বর্তমান চলমান পরিষেবাগুলি দেখুন এবং নিয়ন্ত্রণ করুন"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"রাতের মোড"</string>
@@ -299,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"রঙ সংশোধন"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - আনুমানিক <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string>
@@ -314,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"প্রশাসক দ্বারা অক্ষমিত"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"হোম"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> আগে"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> বাকী আছে"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml
index f09e1ca..8da12cb 100644
--- a/packages/SettingsLib/res/values-bs-rBA/strings.xml
+++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml
@@ -148,10 +148,10 @@
     <string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Uklonjene aplikacije"</string>
     <string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Uklonjene aplikacije i korisnici"</string>
     <string name="tether_settings_title_usb" msgid="6688416425801386511">"USB dijeljenje veze"</string>
-    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prenosna pristupna tačka"</string>
+    <string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prijenosna pristupna tačka"</string>
     <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Dijeljenje Bluetooth veze"</string>
     <string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Dijeljenje veze"</string>
-    <string name="tether_settings_title_all" msgid="8356136101061143841">"Dijeljenje internetske veze i prenosna pristupna tačka"</string>
+    <string name="tether_settings_title_all" msgid="8356136101061143841">"Dijeljenje internetske veze i prijenosna pristupna tačka"</string>
     <string name="managed_user_title" msgid="8101244883654409696">"Profil za Work"</string>
     <string name="user_guest" msgid="8475274842845401871">"Gost"</string>
     <string name="unknown" msgid="1592123443519355854">"Nepoznato"</string>
@@ -170,7 +170,7 @@
     <string name="tts_play_example_summary" msgid="8029071615047894486">"Reproduciraj kratku demonstraciju sintetiziranja govora"</string>
     <string name="tts_install_data_title" msgid="4264378440508149986">"Instaliraj glasovne podatke"</string>
     <string name="tts_install_data_summary" msgid="5742135732511822589">"Instalirajte glasovne podatke potrebne za sintetiziranje govora"</string>
-    <string name="tts_engine_security_warning" msgid="8786238102020223650">"Ovaj program za sintetiziranje govora može biti u mogućnosti da prikuplja sav tekst koji se izgovara, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Potiče od aplikacije <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Da li želite koristiti ovaj program za sintetiziranje govora?"</string>
+    <string name="tts_engine_security_warning" msgid="8786238102020223650">"Ovaj program za sintetiziranje govora u mogućnosti je da prikuplja sav tekst koji se izgovara, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Program omogućava aplikacija <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Da li želite koristiti ovaj program za sintetiziranje govora?"</string>
     <string name="tts_engine_network_required" msgid="1190837151485314743">"Ovaj jezik zahtijeva mrežnu vezu radi za izlaz tekst-u-govor."</string>
     <string name="tts_default_sample_string" msgid="4040835213373086322">"Ovo je primjer sinteze govora"</string>
     <string name="tts_status_title" msgid="7268566550242584413">"Zadani status jezika"</string>
@@ -226,6 +226,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopustiti Wi-Fi lutajuće skeniranje"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Koristi zastareli DHCP klijent"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobilni podaci uvijek aktivni"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogućite apsolutnu jačinu zvuka"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži opcije za certifikaciju Bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećajte nivo Wi-Fi zapisivanja, pokazati po SSID RSSI Wi-Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kada je omogućeno, Wi-Fi će biti agresivniji u predavanju podatkovne veze mobilnoj, kada je Wi-Fi signal slab"</string>
@@ -240,12 +241,13 @@
     <string name="legacy_dhcp_client_summary" msgid="163383566317652040">"Koristi DHCP klijent iz Lollipopa umjesto novog Android DHCP klijenta."</string>
     <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Uvijek drži mobilne podatke aktivnim, čak i kada je Wi-Fi je aktivan (za brzo prebacivanje između mreža)."</string>
     <string name="adb_warning_title" msgid="6234463310896563253">"Omogućiti USB otklanjanje grešaka?"</string>
-    <string name="adb_warning_message" msgid="7316799925425402244">"USB otklanjanje grešaka je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz dnevnika rada."</string>
+    <string name="adb_warning_message" msgid="7316799925425402244">"USB otklanjanje grešaka je namijenjeno samo u svrhe razvoja aplikacija. Koristite ga za kopiranje podataka između računara i uređaja, instaliranje aplikacija na uređaj bez obavještenja te čitanje podataka iz zapisnika."</string>
     <string name="adb_keys_warning_message" msgid="5659849457135841625">"Opozvati pristup otklanjanju grešaka USB-om za sve računare koje ste prethodno ovlastili?"</string>
     <string name="dev_settings_warning_title" msgid="7244607768088540165">"Dopustiti postavke za razvoj?"</string>
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ove postavke su namijenjene samo za svrhe razvoja. Mogu izazvati pogrešno ponašanje uređaja i aplikacija na njemu."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikuj aplikacije putem USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Provjerava da li se u aplikacijama instaliranim putem ADB-a/ADT-a javlja zlonamerno ponašanje."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućava opciju Bluetooth apsolutne jačine zvuka u slučaju problema s jačinom zvuka na udaljenim uređajima, kao što je neprihvatljivo glasan zvuk ili nedostatak kontrole."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući terminalnu aplik. koja nudi pristup lok. kom. okruženju"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provjeravanje"</string>
@@ -268,7 +270,7 @@
     <string name="pointer_location" msgid="6084434787496938001">"Lokacija pokazivača"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Trenutni podaci o dodirivanju prikazuje se u nadsloju preko ekrana"</string>
     <string name="show_touches" msgid="2642976305235070316">"Prikaži dodirivanja"</string>
-    <string name="show_touches_summary" msgid="6101183132903926324">"Prikaži vizualne povratne podatke za dodirivanja"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Prikaži vizuelne povratne informacije za dodirivanja"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Prikaži ažuriranja za površinu"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Prikazi cijele površine prozora uz treptanje prilikom ažuriranja"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Pok. ažur. za GPU prikaz"</string>
@@ -293,9 +295,9 @@
     <string name="force_msaa" msgid="7920323238677284387">"Prinudno primjeni 4x MSAA"</string>
     <string name="force_msaa_summary" msgid="9123553203895817537">"Omogući 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
     <string name="show_non_rect_clip" msgid="505954950474595172">"Ispravi pogreške na nepravougaonim operacijama isecanja"</string>
-    <string name="track_frame_time" msgid="6146354853663863443">"Iscrtavanje GPU profila"</string>
+    <string name="track_frame_time" msgid="6146354853663863443">"Profil GPU iscrtavanja"</string>
     <string name="window_animation_scale_title" msgid="6162587588166114700">"Skala animacije prozora"</string>
-    <string name="transition_animation_scale_title" msgid="387527540523595875">"Skaliranje animacije prelaza"</string>
+    <string name="transition_animation_scale_title" msgid="387527540523595875">"Skaliranje animacije prijelaza"</string>
     <string name="animator_duration_scale_title" msgid="3406722410819934083">"Skala trajanja animatora"</string>
     <string name="overlay_display_devices_title" msgid="5364176287998398539">"Simuliraj sekundarne ekrane"</string>
     <string name="debug_applications_category" msgid="4206913653849771549">"Aplikacije"</string>
@@ -316,9 +318,9 @@
     <skip />
     <!-- no translation found for enable_freeform_support_summary (2252563497485436534) -->
     <skip />
-    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za rezervnu kopiju za radnu površinu"</string>
+    <string name="local_backup_password_title" msgid="3860471654439418822">"Lozinka za rezervnu kopiju radne površine"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da biste promijenili ili uklonili lozinku za potpune rezervne kopije sa radne površine"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije sa radne površine"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nova lozinka za rezervnu kopiju postavljena"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nova lozinka i potvrda se ne podudaraju"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nije uspjelo postavljanje lozinke za rezervnu kopiju"</string>
@@ -373,6 +375,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ispravka boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo vreme je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije"</string>
@@ -388,6 +392,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogućio administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Početna stranica"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index bfca381..333868b 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permet sempre cerca de Wi-Fi en ininerància"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Utilitza el client DHCP heretat"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dades mòbils sempre actives"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactiva el volum absolut"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra les opcions de certificació de pantalla sense fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Augmenta nivell de registre Wi‑Fi i mostra\'l per SSID RSSI al Selector de Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Si s\'activa, la Wi-Fi serà més agressiva en transferir la connexió de dades al mòbil, si el senyal de la Wi-Fi no és estable"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Aquesta configuració només està prevista per a usos de desenvolupament. Pot fer que el dispositiu i que les aplicacions s\'interrompin o tinguin un comportament inadequat."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica aplicacions per USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Comprova les aplicacions instal·lades mitjançant ADB/ADT per detectar possibles comportaments perillosos"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desactiva la funció de volum absolut de Bluetooth en cas que es produeixin problemes de volum amb dispositius remots, com ara un volum massa alt o una manca de control."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Activa l\'aplicació de terminal que ofereix accés al shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Comprovació HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correcció del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: falten aproximadament <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Opció desactivada per l\'administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Inici"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index beba7c3..e219959 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povolit Wi-Fi roaming"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Použít starý klient DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobilní data jsou vždy aktivní"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázat absolutní hlasitost"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobrazit možnosti certifikace bezdrátového displeje"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšit úroveň protokolování Wi‑Fi zobrazenou v SSID a RSSI při výběru sítě Wi‑Fi."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Pokud je tato možnost zapnuta, bude síť Wi-Fi agresivnější při předávání datového připojení mobilní síti při slabém signálu Wi-Fi."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Tato nastavení jsou určena pouze pro vývojáře. Mohou způsobit rozbití nebo nesprávné fungování zařízení a nainstalovaných aplikací."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ověřit aplikace z USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrolovat škodlivost aplikací nainstalovaných pomocí nástroje ADB/ADT"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Zakáže funkci absolutní hlasitosti Bluetooth. Zabrání tak problémům s hlasitostí vzdálených zařízení (jako je příliš vysoká hlasitost nebo nemožnost ovládání)."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Místní terminál"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktivovat terminálovou aplikaci pro místní přístup k prostředí shell"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Kontrola HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Rozblikat obrazovku při dlouhých operacích hlavního vlákna"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Umístění ukazatele"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Zobrazit překryvnou vrstvu s aktuálními daty o dotycích"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Zobrazovat klepnutí"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Zobrazování vizuální zpětné vazby pro klepnutí"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Zobrazit obnovení obsahu"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Rozblikat obsah okna při aktualizaci"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Zobrazit obnovení s GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktivuje podporu experimentálních oken s volným tvarem."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Heslo pro zálohy v počítači"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Úplné zálohy v počítači nejsou v současné době chráněny"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tuto možnost vyberte, chcete-li změnit nebo odebrat heslo pro úplné zálohy do počítače"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nové heslo pro zálohy je nastaveno"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nové heslo se neshoduje s potvrzením hesla."</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nastavení hesla pro zálohy selhalo"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Barvy optimalizované pro digitální obsah"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Neaktivní aplikace"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Neaktivní. Klepnutím možnost přepnete."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktivní. Klepnutím možnost přepnete."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Spuštěné služby"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Umožňuje zobrazit a ovládat aktuálně spuštěné služby"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Noční režim"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekce barev"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Zakázáno administrátorem"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Plocha"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index f00a49a..6acdcc7 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillad altid scanning af Wi-Fi-roaming"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Brug ældre DHCP-klient"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobildata altid aktiveret"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Deaktiver absolut lydstyrke"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis valgmuligheder for certificering af trådløs skærm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øg mængden af Wi‑Fi-logføring. Vis opdelt efter SSID RSSI i Wi‑Fi-vælgeren"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Når dette er aktiveret, gennemtvinges en overdragelse af dataforbindelsen fra Wi-Fi til mobilnetværk, når Wi-Fi-signalet er svagt"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Disse indstillinger er kun beregnet til brug i forbindelse med udvikling. De kan forårsage, at din enhed og dens applikationer går ned eller ikke fungerer korrekt."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Kontrollér apps via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrollér apps, der er installeret via ADB/ADT, for skadelig adfærd."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Deaktiverer funktionen til absolut lydstyrke via Bluetooth i tilfælde af problemer med lydstyrken på eksterne enheder, f.eks. uacceptabel høj lyd eller manglende kontrol."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktivér terminalappen, der giver lokal shell-adgang"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-kontrol"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Blink med skærmen, når apps foretager handlinger på hovedtråd"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Markørens placering"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Skærmoverlejringen viser de aktuelle berøringsdata"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Vis tryk"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Vis visuel feedback ved tryk"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Vis overfladeopdateringer"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Fremhæv hele vinduesoverflader, når de opdateres"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Vis opdat. af GPU-eksp."</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktiverer understøttelse af eksperimentelle vinduer i frit format."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Kode til lokal sikkerhedskopi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Lokale fuldstændige sikkerhedskopieringer er i øjeblikket ikke beskyttet"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal sikkerhedskopiering"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Ny adgangskode til sikkerhedskopi er angivet"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Ny adgangskode og bekræftelse matcher ikke"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Fejl ved angivelse af adgangskode til sikkerhedskopi"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Farver, der er optimeret til digitalt indhold"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Inaktive apps"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inaktiv. Tryk for at skifte."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktiv. Tryk for at skifte."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Kørende tjenester"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Vis og kontrollér kørende tjenester"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Nattilstand"</string>
@@ -299,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korriger farver"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet"</string>
@@ -314,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Deaktiveret af administratoren"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Start"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> siden"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> tilbage"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index e39e464..5f4f60b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"WLAN-Roamingsuchen immer zulassen"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Alten DHCP-Client verwenden"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobile Datennutzung immer aktiviert"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Maximallautstärke deaktivieren"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Level für WLAN-Protokollierung erhöhen, in WiFi Picker pro SSID-RSSI anzeigen"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Wenn diese Option aktiviert ist, ist WLAN bei schwachem Signal bei der Übergabe der Datenverbindung an den Mobilfunk aggressiver."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Diese Einstellungen sind ausschließlich für Entwicklungszwecke gedacht. Sie können dein Gerät und die darauf installierten Apps beschädigen oder zu unerwünschtem Verhalten führen."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Apps über USB bestätigen"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Überprüft installierte Apps über ADB/ADT auf schädliches Verhalten"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Deaktiviert die Bluetooth-Maximallautstärkefunktion, falls auf Remote-Geräten Probleme mit der Lautstärke auftreten, wie beispielsweise übermäßig laute Wiedergabe oder fehlende Kontrolle bei der Steuerung."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokales Terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Terminal-App mit Zugriff auf lokale Shell aktivieren"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-Prüfung"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Farbkorrektur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion. Dies kann sich auf die Leistung auswirken."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch etwa <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Vom Administrator deaktiviert"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Startseite"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index e71d406..826e823 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Να επιτρέπεται πάντα η σάρωση Wi-Fi κατά την περιαγωγή"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Χρήση εφαρμογής-πελάτη DHCP παλαιού τύπου"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Πάντα ενεργά δεδομένα κινητής τηλεφωνίας"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Απενεργοποίηση απόλυτης έντασης"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Εμφάνιση επιλογών για πιστοποίηση ασύρματης οθόνης"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Αύξηση επιπέδου καταγ. Wi-Fi, εμφάνιση ανά SSID RSSI στο εργαλείο επιλογής Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Όταν είναι ενεργό, το Wi-Fi θα μεταβιβάζει πιο επιθετικά τη σύνδ.δεδομένων σε δίκτυο κινητής τηλ., όταν το σήμα Wi-Fi είναι χαμηλό"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Αυτές οι ρυθμίσεις προορίζονται για χρήση κατά την ανάπτυξη. Μπορούν να προκαλέσουν προβλήματα στη λειτουργία της συσκευής και των εφαρμογών σας."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Επαλήθευση εφαρμογών μέσω USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Έλεγχος εφαρμογών που έχουν εγκατασταθεί μέσω ADB/ADT για επιβλαβή συμπεριφορά."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Απενεργοποιεί τη δυνατότητα απόλυτης έντασης του Bluetooth σε περίπτωση προβλημάτων έντασης με απομακρυσμένες συσκευές, όπως όταν υπάρχει μη αποδεκτά υψηλή ένταση ή απουσία ελέγχου."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Τοπική τερματική εφαρμογή"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Ενεργοπ.τερμ.εφαρμογής που προσφέρει πρόσβαση στο τοπικό κέλυφος"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Έλεγχος HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Διόρθωση χρωμάτων"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Απενεργοποιήθηκε από το διαχειριστή"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Αρχική οθόνη"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index dd15245..481cc47 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Use legacy DHCP client"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobile data always active"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to Mobile, when Wi‑Fi signal is low"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behaviour."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Disabled by administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Home"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index dd15245..481cc47 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Use legacy DHCP client"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobile data always active"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to Mobile, when Wi‑Fi signal is low"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behaviour."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Disabled by administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Home"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index dd15245..481cc47 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Always allow Wi‑Fi Roam Scans"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Use legacy DHCP client"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobile data always active"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disable absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Show options for wireless display certification"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Increase Wi‑Fi logging level, show per SSID RSSI in Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"When enabled, Wi‑Fi will be more aggressive in handing over the data connection to Mobile, when Wi‑Fi signal is low"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"These settings are intended for development use only. They can cause your device and the applications on it to break or misbehave."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verify apps over USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Check apps installed via ADB/ADT for harmful behaviour."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Local terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Enable terminal app that offers local shell access"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP checking"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Colour correction"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Disabled by administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Home"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ago"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> left"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 09d5695..7380240 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usar cliente DHCP heredado"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Datos móviles siempre activos"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones de certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar nivel de registro Wi-Fi; mostrar por SSID RSSI en el selector de Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Si está habilitada, la conexión Wi‑Fi será más intensa al transferir la conexión de datos al celular (si la señal Wi‑Fi es débil)."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Estos parámetros de configuración están destinados únicamente a los programadores. Pueden hacer que el dispositivo o sus aplicaciones no funcionen correctamente."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar aplicaciones por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Comprobar que las aplicaciones instaladas mediante ADB/ADT no ocasionen daños"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (por ejemplo, volumen demasiado alto o falta de control)."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Habilitar aplicac. de terminal que ofrece acceso al shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Comprobación HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección de color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: alrededor de <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Inhabilitada por el administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Página principal"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 79c35e1..1cf51fe 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir siempre búsquedas de Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usar cliente DHCP heredado"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Datos móviles siempre activos"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inhabilitar volumen absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opciones para la certificación de la pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar el nivel de logging de Wi-Fi, mostrar por SSID RSSI en el selector Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Si está habilitada, la conexión Wi‑Fi será más agresiva al transferir la conexión de datos al móvil (si la señal Wi‑Fi no es estable)"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Estos ajustes están destinados únicamente a los desarrolladores. Pueden provocar que el dispositivo o las aplicaciones no funcionen correctamente."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar aplicaciones por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Comprueba las aplicaciones instaladas mediante ADB/ADT para detectar comportamientos dañinos"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Inhabilita la función de volumen absoluto de Bluetooth si se producen problemas de volumen con dispositivos remotos (por ejemplo, volumen demasiado alto o falta de control)."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Habilitar aplicación de terminal que ofrece acceso a shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Comprobación de HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Parpadear si las aplicaciones tardan mucho en el thread principal"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Ubicación del puntero"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Superponer los datos de las pulsaciones en la pantalla"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Mostrar toques"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Mostrar la ubicación de los toques en la pantalla"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Cambios de superficie"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Actualizar superficies de ventana al actualizarse"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Actualizaciones GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Permite utilizar ventanas de forma libre experimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contraseña para copias de ordenador"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Las copias de seguridad completas de ordenador no están protegidas"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca para cambiar o quitar la contraseña de las copias de seguridad completas del escritorio"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nueva contraseña de seguridad establecida"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"La nueva contraseña y la de confirmación no coinciden"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Error al establecer la contraseña de seguridad"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Colores optimizados para contenido digital"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Aplicaciones inactivas"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Inactiva. Toca para alternar."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Activa. Toca para alternar."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Servicios en ejecución"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Ver y controlar los servicios en ejecución"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Modo nocturno"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección del color"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quedan <xliff:g id="TIME">%2$s</xliff:g> aproximadamente"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Inhabilitada por el administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Inicio"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml
index 2f9532b..c5153ff 100644
--- a/packages/SettingsLib/res/values-et-rEE/strings.xml
+++ b/packages/SettingsLib/res/values-et-rEE/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luba alati WiFi-rändluse skannimine"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"DHCP pärandkliendi kasutamine"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobiilne andmeside on alati aktiivne"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Keela absoluutne helitugevus"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Juhtmeta ekraaniühenduse sertifitseerimisvalikute kuvamine"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Suurenda WiFi logimistaset, kuva WiFi valijas SSID RSSI järgi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kui see on lubatud, siis püüab WiFi nõrga WiFi-signaali korral agressiivsemalt anda andmeside ühenduse üle mobiilsele andmesidele"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Need seaded on mõeldud ainult arendajatele. Need võivad põhjustada seadme ja seadmes olevate rakenduste rikkeid või valesti toimimist."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Kinnita rakendus USB kaudu"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrolli, kas ADB/ADT-ga installitud rakendused on ohtlikud."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Keelatakse Bluetoothi absoluutse helitugevuse funktsioon, kui kaugseadmetega on helitugevuse probleeme (nt liiga vali heli või juhitavuse puudumine)."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Kohalik terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Luba kohalikku turvalist juurdepääsu pakkuv terminalirakendus"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-kontrollimine"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värviparandus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%2$s</xliff:g> on jäänud"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – jäänud on umbes <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administraator on keelanud"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Avaekraan"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> tagasi"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> on jäänud"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 8cd36fa..1e06c6a 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Onartu beti ibiltaritzan Wi-Fi sareak bilatzea"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Erabili aurreko bertsioko DHCP bezeroa"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mugikorreko datuak beti aktibo"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desgaitu bolumen absolutua"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Erakutsi hari gabeko bistaratze-egiaztapenaren aukerak"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Erakutsi datu gehiago Wi-Fi sareetan saioa hasterakoan. Erakutsi sarearen identifikatzailea eta seinalearen indarra Wi‑Fi sareen hautagailuan."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Aukera hori gaituz gero, gailua errazago aldatuko da datu mugikorren konexiora Wi-Fi seinalea ahultzen dela nabaritutakoan"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ezarpen hauek garapen-xedeetarako pentsatu dira soilik. Baliteke ezarpenen eraginez gailua matxuratzea edo funtzionamendu okerra izatea."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Egiaztatu USBko aplikazioak."</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Egiaztatu ADB/ADT bidez instalatutako aplikazioak portaera kaltegarriak antzemateko."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desgaitu egiten du Bluetooth bidezko bolumen absolutuaren eginbidea urruneko gailuetan arazoak hautematen badira; esaterako, bolumena ozenegia bada edo ezin bada kontrolatu."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Tokiko terminala"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Gaitu tokiko shell-sarbidea duen terminal-aplikazioa"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP egiaztapena"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kolore-zuzenketa"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> inguru. <xliff:g id="TIME">%2$s</xliff:g> geratzen d(ir)a"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administratzaileak desgaitu du"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Hasierako pantaila"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index dd6d0c4..e023f247 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏اسکن‌های رومینگ Wi‑Fi همیشه مجاز است"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"‏استفاده از کلاینت DHCP قدیمی"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"داده سلولی همیشه فعال"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"غیرفعال کردن میزان صدای مطلق"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"نمایش گزینه‌ها برای گواهینامه نمایش بی‌سیم"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏افزایش سطح گزارش‌گیری Wi‑Fi، نمایش به ازای SSID RSSI در انتخاب‌کننده Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"‏وقتی فعال است، در شرایط پایین بودن سیگنال، Wi‑Fi برای واگذار کردن اتصال داده به شبکه سلولی فعال‌تر خواهد بود."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"این تنظیمات فقط برای برنامه‌نویسی در نظر گرفته شده است. ممکن است استفاده از این تنظیمات موجب خرابی یا عملکرد نادرست دستگاه یا برنامه‌های شما شود."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"‏تأیید برنامه‌های نصب شده از طریق USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"‏برنامه‌های نصب شده از طریق ADB/ADT را ازنظر رفتار مخاطره‌آمیز بررسی کنید."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"در صورت وجود مشکل میزان صدا با دستگاه‌های راه دور مثل میزان صدای بلند ناخوشایند یا عدم کنترل صدا، قابلیت میزان صدای کامل بلوتوث را غیرفعال کنید."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ترمینال محلی"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"فعال کردن ترمینال برنامه‌ کاربردی که دسترسی به برنامه محلی را پیشنهاد می‌کند"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"‏بررسی HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"چشمک زدن صفحه هنگام انجام عملیات طولانی توسط برنامه‌ها در رشته اصلی"</string>
     <string name="pointer_location" msgid="6084434787496938001">"محل اشاره‌گر"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"هم‌پوشانی صفحهٔ نمایش با نمایش داده لمسی فعلی"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"نمایش ضربه‌ها"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"نمایش بازخورد تصویری برای ضربه‌ها"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"نمایش به‌روزرسانی سطح"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"هنگام به‌روزرسانی سطوح پنجره همه فلش شوند"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"‏نمایش به روزرسانی‌های نمای GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"پشتیبانی برای پنجره‌های آزاد آزمایشی را امکان‌پذیر می‌کند"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"گذرواژه پشتیبان‌گیری محلی"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"پشتیبان‌گیری کامل رایانه درحال حاضر محافظت نمی‌شود"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"برای تغییر یا حذف گذرواژه برای نسخه‌های پشتیبان کامل رایانه‌ای ضربه بزنید"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"گذرواژه جدید نسخهٔ پشتیبان تنظیم شد"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"گذرواژه جدید و تأیید آن با یکدیگر مطابقت ندارند"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"گذرواژه پشتیبان‌گیری تنظیم نشد"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"رنگ‌های بهینه‌شده برای محتوای دیجیتالی"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"برنامه‌های غیرفعال"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"غیرفعال. برای تغییر حالت ضربه بزنید."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"فعال. برای تغییر حالت ضربه بزنید."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"سرویس‌های در حال اجرا"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"مشاهده و کنترل سرویس‌های در حال اجرای فعلی"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"حالت شب"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"تصحیح رنگ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً ‏<xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمی‌شود"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"سرپرست آن را غیرفعال کرده است"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"صفحه اصلی"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 2f3f5da..c4f572c 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Salli Wi-Fi-verkkovierailuskannaus aina"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Käytä vanhaa DHCP-asiakassovellusta"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobiilidata on aina käytössä"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Poista yleinen äänenvoimakkuuden säätö käytöstä"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Näytä langattoman näytön sertifiointiin liittyvät asetukset"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Lisää Wi‑Fin lokikirjaustasoa, näytä SSID RSSI -kohtaisesti Wi‑Fi-valitsimessa."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kun asetus on käytössä, Wi-Fi siirtää datayhteyden aggressiivisemmin matkapuhelinverkolle, jos Wi-Fi-signaali on heikko."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Nämä asetukset on tarkoitettu vain kehityskäyttöön, ja ne voivat aiheuttaa haittaa laitteellesi tai sen sovelluksille."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Tarkista USB:n kautta asennetut"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Tarkista ADB:n/ADT:n kautta asennetut sovellukset haitallisen toiminnan varalta."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Bluetoothin yleinen äänenvoimakkuuden säätö poistetaan käytöstä ongelmien välttämiseksi esimerkiksi silloin, kun laitteen äänenvoimakkuus on liian kova tai sitä ei voi säätää."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Paikallinen pääte"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Ota käyttöön päätesov. joka mahdollistaa paikall. liittymäkäytön"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-tarkistus"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Värikorjaus"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Järjestelmänvalvojan käytöstä poistama"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Aloitusnäyttö"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 679d209..f888ec8 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Utiliser l\'ancien client DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Données cellulaires toujours actives"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options pour la certification d\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler davantage les données Wi-Fi, afficher par SSID RSSI dans sélect. Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Si cette option est activée, le passage du Wi-Fi aux données cellulaires est forcé lorsque le signal Wi-Fi est faible"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applications qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Vérifier les applis via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Vérifiez que les applications installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Désactive la fonctionnalité de volume absolu par Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Vérification HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Afficher un cadre rouge si le thread principal reste occupé"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Emplacement du curseur"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Superposition écran indiquant données actuelles"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Afficher éléments sélect."</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Afficher repère visuel pour éléments sélectionnés"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Affich. mise à jour surface"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Faire clignoter les surfaces à chaque mise à jour"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Afficher mises à jour GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Active la compatibilité avec les fenêtres de forme libre expérimentales."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Mot de passe sauvegarde PC"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement."</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Touchez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur ordinateur."</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Le nouveau mot de passe de secours a bien été défini."</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Le nouveau mot de passe et sa confirmation ne correspondent pas."</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Échec de la définition du mot de passe de secours."</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Couleurs optimisées pour le contenu numérique"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Applications inactives"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Application inactive. Touchez ici pour l\'activer."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Application active. Touchez ici pour la désactiver."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Services en cours d\'exécution"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Afficher et contrôler les services en cours d\'exécution"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Mode Nuit"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction des couleurs"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut toucher les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> %% – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Désactivé par l\'administrateur"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Accueil"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 556edaf..dfc71f1 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Toujours autoriser la détection de réseaux Wi-Fi en itinérance"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Utiliser l\'ancien client DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Données mobiles toujours actives"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Désactiver le volume absolu"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afficher les options de la certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Détailler plus infos Wi-Fi, afficher par RSSI de SSID dans outil sélection Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Si cette option est activée, le passage du Wi-Fi aux données mobiles est forcé en cas de signal Wi-Fi faible."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applications qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Vérifier les applis via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Vérifiez que les applications installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Désactive la fonctionnalité de volume absolu du Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Vérification HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correction couleur"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g> environ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Désactivé par l\'administrateur"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Accueil"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml
index ca49d2d..20985bd 100644
--- a/packages/SettingsLib/res/values-gl-rES/strings.xml
+++ b/packages/SettingsLib/res/values-gl-rES/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre buscas de itinerancia da wifi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usar cliente DHCP herdado"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Datos móbiles sempre activados"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desactivar volume absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opcións para o certificado de visualización sen fíos"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nivel de rexistro da wifi, mostrar por SSID RSSI no selector de wifi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Cando está activada esta función, a wifi será máis agresiva ao entregar a conexión de datos ao móbil, cando o sinal wifi é feble"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Esta configuración só está destinada á programación. Esta pode provocar que o dispositivo e as aplicacións fallen ou se comporten incorrectamente."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar aplicacións por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Comprobar as aplicacións instaladas a través de ADB/ADT para detectar comportamento perigoso."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desactiva a función do volume absoluto do Bluetooth en caso de que se produzan problemas de volume cos dispositivos remotos, como volume demasiado alto ou falta de control."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Activa a aplicación terminal que ofrece acceso ao shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Comprobación HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Pestanexa se aplicacións tardan moito no proceso principal"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Localización do punteiro"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Superpoñer datos dos toques na pantalla"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Mostrar toques"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Mostra a información visual dos toques"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Cambios de superficie"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Iluminar superficies de ventás ao actualizarse"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Actualizacións GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Activa a compatibilidade con ventás de forma libre experimentais."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Contrasinal para copias"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"As copias de seguridade de ordenador completas non están protexidas"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Toca para cambiar ou eliminar o contrasinal para as copias de seguranza completas do escritorio"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Novo contrasinal de copia de seguranza definido"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"O contrasinal novo e a confirmación non coinciden"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Erro ao definir un contrasinal de copia de seguranza"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Cores optimizadas para contido dixital"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Aplicacións inactivas"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Aplicación inactiva. Toca para alternar a configuración."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aplicación activa. Toca para alternar a configuración."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Servizos en execución"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Ver e controlar servizos actualmente en execución"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Modo nocturno"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corrección da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - faltan aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desactivado polo administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Inicio"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 2aa8c5f..18917e0 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"હંમેશા Wi‑Fi રોમ સ્કૅન્સને મંજૂરી આપો"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"લેગેસી DHCP ક્લાઇન્ટનો ઉપયોગ કરો"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"સેલ્યુલર ડેટા હંમેશા સક્રિય"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ચોક્કસ વૉલ્યૂમને અક્ષમ કરો"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"વાયરલેસ ડિસ્પ્લે પ્રમાણપત્ર માટેના વિકલ્પો બતાવો"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi લોગિંગ સ્તર વધારો, Wi‑Fi પીકરમાં SSID RSSI દીઠ બતાવો"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"જ્યારે સક્ષમ હોય, ત્યારે Wi‑Fi સિગ્નલ ઓછા હોવા પર, સેલ્યુલર પર ડેટા કનેક્શન મોકલવામાં વધુ આક્રમક હશે"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"આ સેટિંગ્સ ફક્ત વિકાસનાં ઉપયોગ માટે જ હેતુબદ્ધ છે. તે તમારા ઉપકરણ અને તેના પરની એપ્લિકેશન્સનાં ભંગ થવા અથવા ખરાબ વર્તનનું કારણ બની શકે છે."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB પર એપ્લિકેશનો ચકાસો"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"હાનિકારક વર્તણૂંક માટે ADB/ADT મારફતે ઇન્સ્ટોલ કરવામાં આવેલી એપ્લિકેશનો તપાસો."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"રિમોટ ઉપકરણોમાં વધુ પડતું ઊંચું વૉલ્યૂમ અથવા નિયંત્રણની કમી જેવી વૉલ્યૂમની સમસ્યાઓની સ્થિતિમાં Bluetooth ચોક્કસ વૉલ્યૂમ સુવિધાને અક્ષમ કરે છે."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"સ્થાનિક ટર્મિનલ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"સ્થાનિક શેલ અ‍ૅક્સેસની ઑફર કરતી ટર્મિનલ એપ્લિકેશનને સક્ષમ કરો"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP તપાસણી"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"રંગ સુધારણા"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - આશરે <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"સંપૂર્ણ થવામાં <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"વ્યવસ્થાપક દ્વારા અક્ષમ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"હોમ"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 8f382c5..32b2814 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"हमेशा वाई-फ़ाई रोम स्कैन करने दें"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"लीगेसी DHCP क्‍लाइंट"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"सेल्युलर डेटा हमेशा सक्रिय"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"पूर्ण वॉल्यूम अक्षम करें"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस दिखाई देने के लिए प्रमाणन विकल्प दिखाएं"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाई-फ़ाई प्रवेश स्तर बढ़ाएं, वाई-फ़ाई पिकर में प्रति SSID RSSI दिखाएं"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"इसके सक्षम होने पर, जब वाई-फ़ाई संकेत कमज़ोर हों तो वाई-फ़ाई, डेटा कनेक्शन को सेल्यूलर पर अधिक बलपूर्वक भेजेगा"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ये सेटिंग केवल विकास संबंधी उपयोग के प्रयोजन से हैं. वे आपके डिवाइस और उस पर स्‍थित ऐप्स  को खराब कर सकती हैं या उनके दुर्व्यवहार का कारण हो सकती हैं."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB पर ऐप्स  सत्यापित करें"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"नुकसानदेह व्यवहार के लिए ADB/ADT के द्वारा इंस्टॉल किए गए ऐप्स  जांचें."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"दूरस्थ डिवाइस के साथ वॉल्यूम की समस्याओं जैसे अस्वीकार्य तेज़ वॉल्यूम या नियंत्रण की कमी की स्थिति में ब्लूटूथ पूर्ण वॉल्यूम सुविधा को अक्षम करता है."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"स्थानीय टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"स्थानीय शेल एक्सेस ऑफ़र करने वाला टर्मिनल ऐप्स  सक्षम करें"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP जांच"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी होने तक"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"व्यवस्थापक के द्वारा अक्षम किया गया"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"होम"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहले"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शेष"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 266e4d7..37b5363 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Uvijek dopusti slobodno traženje Wi-Fi mreže"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Upotrebljavaj stari DHCP klijent"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobilni podaci uvijek aktivni"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogući apsolutnu glasnoću"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Prikaži opcije za certifikaciju bežičnog prikaza"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povećana razina prijave na Wi‑Fi, prikaz po SSID RSSI-ju u Biraču Wi‑Fi-ja"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Ako je omogućeno, Wi-Fi će aktivno prebacivati podatkovnu vezu mobilnoj mreži kada je Wi-Fi signal slab."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ove su postavke namijenjene samo razvojnim programerima. One mogu uzrokovati kvar ili neželjeno ponašanje vašeg uređaja i aplikacija na njemu."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Potvrdi aplikacije putem USB-a"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Provjerite uzrokuju li aplikacije instalirane putem ADB-a/ADT-a poteškoće."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogućuje Bluetoothovu značajku apsolutne glasnoće ako udaljeni uređaji imaju poteškoća sa zvukom, kao što su, primjerice, neprihvatljiva glasnoća ili nepostojanje kontrole."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogući aplikaciju terminala koja nudi pristup lokalnoj ovojnici"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP provjera"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcija boje"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – još približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogućio administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Početni zaslon"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Prije <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Još <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index f2dc5ce..9113ab3 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi-roaming ellenőrzésének engedélyezése mindig"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Korábbi DHCP-kliens használata"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"A mobilhálózati adatforgalom mindig aktív"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Abszolút hangerő funkció letiltása"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vezeték nélküli kijelző tanúsítványával kapcsolatos lehetőségek megjelenítése"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-naplózási szint növelése, RSSI/SSID megjelenítése a Wi‑Fi-választóban"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Ha engedélyezi, a Wi-Fi agresszívebben fogja átadni az adatkapcsolatot a mobilhálózatnak gyenge Wi-Fi-jel esetén"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ezek a beállítások csak fejlesztői használatra szolgálnak. Használatuk esetén eszköze vagy alkalmazásai meghibásodhatnak, illetve nem várt módon viselkedhetnek."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB-n keresztül telepített alkalmazások ellenőrzése"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Az ADB/ADT útján telepített alkalmazások ellenőrzése kártékony viselkedésre."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Letiltja a Bluetooth abszolút hangerő funkcióját a távoli eszközökkel kapcsolatos hangerőproblémák – például elfogadhatatlanul magas vagy nem vezérelhető hangerő – esetén."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Helyi végpont"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Végalkalmazás engedélyezése a helyi rendszerhéj eléréséhez"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ellenőrzés"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Színkorrekció"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttség eléréséig"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Letiltva a rendszergazda által"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Főoldal"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Ennyi ideje: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> van hátra"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml
index bd0a339..2baa160 100644
--- a/packages/SettingsLib/res/values-hy-rAM/strings.xml
+++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Միշտ թույլատրել Wi‑Fi ռոումինգի որոնումը"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Օգտագործել DHCP ծրագրի ավելի հին տարբերակները"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Բջջային տվյալները՝ միշտ ակտիվացրած"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Անջատել ձայնի բացարձակ ուժգնությունը"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ցույց տալ անլար էկրանի վկայագրման ընտրանքները"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Բարձրացնել մակարդակը, Wi‑Fi ընտրիչում ամեն մի SSID-ի համար ցույց տալ RSSI"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Եթե այս գործառույթը միացված է, Wi‑Fi-ի թույլ ազդանշանի դեպքում Wi‑Fi ինտերնետից անցումը բջջային ինտերնետին ավելի կտրուկ կլինի"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Այս կարգավորումները միայն ծրագրավորման նպատակների համար են նախատեսված: Դրանք կարող են խանգարել ձեր սարքի կամ ծրագրի աշխատանքին:"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ստուգել հավելվածները USB-ի նկատմամբ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Ստուգեք տեղադրված հավելվածը ADB/ADT-ի միջոցով կասկածելի աշխատանքի պատճառով:"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Կասեցնում է Bluetooth-ի ձայնի բացարձակ ուժգնության գործառույթը՝ հեռավոր սարքերի հետ ձայնի ուժգնությանը վերաբերող խնդիրներ ունենալու դեպքում (օրինակ՝ երբ ձայնի ուժգնությունն անընդունելի է կամ դրա կառավարումը հնարավոր չէ):"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Տեղային տերմինալ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Միացնել տերմինալային հավելվածը, որն առաջարկում է մուտք տեղային խեցի"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ստուգում"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Լուսավորել էկրանը` ծրագրի գլխավոր շղթայի վրա երկար աշխատելիս"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Նշիչի տեղադրություն"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Էկրանի վերադրումը ցույց է տալիս ընթացիկ հպման տվյալները"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Ցույց տալ հպումները"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Ցույց տալ հպումների տեսանելի արձագանքը"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Ցույց տալ մակերեսի թարմացումները"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Թող պատուհանի ամբողջական մակերեսները առկայծեն, երբ թարմացվում են"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Ցույց տալ GPU տեսքի թարմացումները"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Ակտիվացնում է կամայական ձևի փորձնական պատուհանների աջակցումը:"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Աշխատասեղանի պահուստավորման գաղտնաբառ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Աշխատասեղանի ամբողջական պահուստավորումները այժմ պաշտպանված չեն"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Հպեք՝ աշխատասեղանի ամբողջական պահուստավորման գաղտնաբառը փոխելու կամ հեռացնելու համար"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Պահուստավորման նոր գաղտնաբառը սահմանված է"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Նոր գաղտնաբառը և հաստատումը չեն համընկնում"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Ձախողում գաղտնաբառի պահուստավորման կարգավորման ընթացքում"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Թվային բովանդակության համար հարմարեցված գույներ"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Միացրած հավելվածներ"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Ակտիվ չէ: Հպեք՝ փոխելու համար:"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Ակտիվ է: Հպեք՝ փոխելու համար:"</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Աշխատեցվող ծառայություններ"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Դիտել և վերահսկել ընթացիկ աշխատեցվող ծառայությունները"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Գիշերային ռեժիմ"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Գունային կարգաբերում"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել աշխատանքի վրա:"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնաց մոտավորապես <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Կասեցված է ադմինիստրատորի կողմից"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Գլխավոր էջ"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 2aa96d8..1a47576 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Selalu izinkan Pemindaian Roaming Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Gunakan klien DHCP lawas"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Data seluler selalu aktif"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Nonaktifkan volume absolut"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tampilkan opsi untuk sertifikasi layar nirkabel"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan level pencatatan log Wi-Fi, tampilkan per SSID RSSI di Pemilih Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Jika diaktifkan, Wi-Fi akan menjadi lebih agresif dalam mengalihkan sambungan data ke Seluler saat sinyal Wi-Fi lemah"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Setelan ini hanya dimaksudkan untuk penggunaan pengembangan. Setelan dapat menyebabkan perangkat dan aplikasi yang menerapkannya rusak atau tidak berfungsi semestinya."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifikasi aplikasi melalui USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Periksa perilaku membahayakan dalam aplikasi yang terpasang melalui ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Menonaktifkan fitur volume absolut Bluetooth jika ada masalah volume dengan perangkat jarak jauh, misalnya volume terlalu keras atau kurangnya kontrol."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal lokal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktifkan aplikasi terminal yang menawarkan akses kerangka lokal"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Pemeriksaan HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Koreksi warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira tersisa. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dinonaktifkan oleh administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Layar Utama"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index b78cb0b..558f7bc 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Leyfa alltaf reikileit með Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Nota gamlan DHCP-biðlara"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Alltaf kveikt á farsímagögnum"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slökkva á samstillingu hljóðstyrks"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Sýna valkosti fyrir vottun þráðlausra skjáa"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Auka skráningarstig Wi-Fi, sýna RSSI fyrir hvert SSID í Wi-Fi vali"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Þegar þetta er virkt mun Wi-Fi ganga harðar fram í að færa gagnatenginguna yfir til símkerfisins þegar Wi-Fi merkið er lélegt"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Þessar stillingar eru einungis ætlaðar í þróunarskyni. Þær geta valdið því að tækið og forrit þess bili eða starfi á rangan hátt."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Staðfesta forrit gegnum USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kanna skaðlega hegðun forrita sem sett eru upp frá ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Slekkur á samstillingu Bluetooth-hljóðstyrks ef vandamál koma upp með hljóðstyrk hjá fjartengdum tækjum, svo sem of hár hljóðstyrkur eða erfiðleikar við stjórnun."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Staðbundin skipanalína"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Virkja skipanalínuforrit sem leyfir staðbundinn skeljaraðgang"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-athugun"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Blikka skjá ef forrit gera tímafreka hluti á aðalþræði"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Staðsetning bendils"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Skjáyfirlögn sem sýnir rauntímagögn um snertingar"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Sýna snertingar"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Sýna snertingar myndrænt"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Sýna yfirborðsuppfærslur"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Láta allt yfirborð glugga blikka við uppfærslu"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Sýna uppfærslur skjákorts"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Kveikir á stuðningi við glugga með frjálsu sniði á tilraunastigi."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Aðgangsorð tölvuafritunar"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Heildarafritun á tölvu er ekki varin sem stendur."</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ýttu til að breyta eða fjarlægja aðgangsorðið fyrir heildarafritun á tölvu"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nýtt aðgangsorð fyrir afritun valið"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Nýja aðgangsorðið og staðfestingaraðgangsorðið eru ekki eins"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Villa við að velja aðgangsorð fyrir afritun"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Litir sérhannaðir fyrir stafrænt efni"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Óvirk forrit"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Óvirkt. Ýttu til að breyta."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Virkt. Ýttu til að breyta."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Þjónustur í gangi"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Skoða og stjórna þjónustum í gangi"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Næturstilling"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Litaleiðrétting"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Stjórnandi gerði óvirkt"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Heim"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index c8e482e..24564c1 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Consenti sempre scansioni roaming Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usa client DHCP precedente"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dati cellulare sempre attivi"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Disattiva volume assoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostra opzioni per la certificazione display wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumenta il livello di registrazione Wi-Fi, mostrando il SSID RSSI nel selettore Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Quando questa impostazione è attivata, il Wi-Fi sarà più aggressivo nel passare la connessione dati al cellulare, quando il segnale Wi-Fi è basso"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Queste impostazioni sono utilizzabili solo a scopo di sviluppo. Possono causare l\'arresto o il comportamento anomalo del dispositivo e delle applicazioni su di esso."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica app tramite USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Controlla che le applicazioni installate tramite ADB/ADT non abbiano un comportamento dannoso."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Consente di disattivare la funzione del volume assoluto Bluetooth in caso di problemi con il volume dei dispositivi remoti, ad esempio un volume troppo alto o la mancanza di controllo."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminale locale"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Abilita l\'app Terminale che offre l\'accesso alla shell locale"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Verifica HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correzione del colore"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g> circa"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Disattivata dall\'amministratore"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Home page"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index c12a050..5dea0a2 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏התר תמיד סריקות נדידה של Wi‑Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"‏השתמש בלקוח DHCP מדור קודם"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"נתונים סלולריים פעילים תמיד"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"השבת עוצמת קול מוחלטת"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"‏הצג אפשרויות עבור אישור של תצוגת WiFi"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏העלה את רמת הרישום של Wi‑Fi ביומן, הצג לכל SSID RSSI ב-Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"‏כשתכונה זו מופעלת, Wi-Fi יתנהג בצורה אגרסיבית יותר בעת העברת חיבור הנתונים לרשת הסלולרית כשאות ה-Wi-Fi חלש."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"הגדרות אלה מיועדות לשימוש בפיתוח בלבד. הן עלולות לגרום למכשיר או לאפליקציות המותקנות בו לקרוס או לפעול באופן לא תקין."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"‏אמת אפליקציות באמצעות USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"‏בדוק אפליקציות שהותקנו באמצעות ADB/ADT לאיתור התנהגות מזיקה."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"‏משבית את תכונת עוצמת הקול המוחלטת ב-Bluetooth במקרה של בעיות בעוצמת הקול במכשירים מרוחקים, כגון עוצמת קול רמה מדי או חוסר שליטה ברמת העוצמה."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"מסוף מקומי"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"הפעל אפליקציית מסוף המציעה גישה מקומית למעטפת"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"‏בדיקת HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"תיקון צבע"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ‏<xliff:g id="TIME">%2$s</xliff:g> בקירוב עד לסיום"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>‏ - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> ‏- <xliff:g id="TIME">%2$s</xliff:g> עד למילוי"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"הושבת על ידי מנהל המערכת"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"דף הבית"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index c26882c..eb7f8af 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fiローミングスキャンを常に許可する"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"従来のDHCPクライアントを使用する"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"モバイルデータを常にON"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"絶対音量を無効にする"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ワイヤレスディスプレイ認証のオプションを表示"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fiログレベルを上げて、Wi-Fi選択ツールでSSID RSSIごとに表示します"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"有効にすると、Wi-Fiの電波強度が弱い場合は強制的にモバイルデータ接続に切り替わるようになります"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"これらの設定は開発専用に設計されています。そのため端末や端末上のアプリが故障したり正常に動作しなくなったりするおそれがあります。"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB経由のアプリを確認"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT経由でインストールされたアプリに不正な動作がないかを確認する"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"リモート端末で音量に関する問題(音量が大きすぎる、制御できないなど)が発生した場合に、Bluetooth の絶対音量の機能を無効にする。"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ローカルターミナル"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"ローカルシェルアクセスを提供するターミナルアプリを有効にします"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCPチェック"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色補正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -311,6 +315,9 @@
     <!-- no translation found for battery_info_status_full (2824614753861462808) -->
     <skip />
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"管理者によって無効にされています"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"ホーム"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 2a09ec0..540dc81 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Roam სკანირების მუდამ დაშვება"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"მოძველებული DHCP კლიენტის გამოყენება"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ფიჭური მონაცემები ყოველთვის აქტიურია"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ხმის აბსოლუტური სიძლიერის გათიშვა"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"უსადენო ეკრანის სერტიფიცირების ვარიანტების ჩვენება"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi-ს აღრიცხვის დონის გაზრდა, Wi‑Fi ამომრჩეველში ყოველ SSID RSSI-ზე ჩვენება"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"თუ ჩართულია, Wi‑Fi სიგნალის შესუსტების შემთხვევაში Wi-Fi უფრო აქტიურად შეეცდება გადაიყვანოს ინტერნეტ-კავშირი მობილურ ინტერნეტზე"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ამ პარამეტრების გამოყენება დასაშვებია მხოლოდ დეველოპერული მიზნებით. მათმა გამოყენებამ შეიძლება გამოიწვიოს თქვენი მოწყობილობის და მისი აპლიკაციების დაზიანება ან გაუმართავი მუშაობა."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"აპლიკაციების USB-ს საშუალებით შემოწმება"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"შეამოწმეთ, რამდენად უსაფრთხოა ADB/ADT-ის საშუალებით ინსტალირებული აპლიკაციები."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"გათიშავს Bluetooth-ის ხმის აბსოლუტური სიძლიერის ფუნქციას დისტანციურ მოწყობილობებზე ხმასთან დაკავშირებული ისეთი პრობლემების არსებობის შემთხვევაში, როგორიცაა ხმის დაუშვებლად მაღალი სიძლიერე ან კონტროლის შეუძლებლობა."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ადგილობრივი ტერმინალი"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"ლოკალურ გარსზე წვდომის ტერმინალური აპლიკაციის ჩართვა"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP შემოწმება"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Flash screen when apps do long operations on main thread"</string>
     <string name="pointer_location" msgid="6084434787496938001">"მაჩვენებლის მდებარეობა"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"ეკრანის გადაფარვა შეხების მონაცემების ჩვენებით"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"შეხებების ჩვენება"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"შეხებებისთვის ვიზუალური უკუკავშირის ჩვენება"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"ზედაპირის განახლებების ჩვენება"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"ფანჯრის მთელი ზედაპირის აციმციმება მისი განახლებისას"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU ხედის განახლებების ჩვენება"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ჩართავს თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტულ ფუნქციას"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"დესკტოპის სარეზერვო ასლის პაროლი"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"დესკტოპის სრული სარეზერვო ასლები ამჟამად დაცული არ არის"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"შეეხეთ დესკტოპის სრული სარეზერვო ასლების პაროლის შესაცვლელად ან წასაშლელად"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"ახალი სარეზერვო პაროლის დაყენება"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ახალი და დადასტურებული პაროლები არ შეესატყვისება ერთმანეთს"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"სარეზერვო პაროლის დაყენება ვერ მოხერხდა"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"ციფრული კონტენტისთვის ოპტიმიზებული ფერები"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"უმოქმედო აპები"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"უმოქმედო. შეეხეთ გადასართავად."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"აქტიური. შეეხეთ გადასართავად."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"მიმდინარე სერვისები"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"ამჟამად მოქმედი სერვისების ნახვა და მართვა"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"ღამის რეჟიმი"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ფერის კორექცია"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს შესრულებაზე."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"დაახლ. <xliff:g id="LEVEL">%1$s</xliff:g> დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> სრულ დატენვამდე"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"გათიშულია ადმინისტრატორის მიერ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"მთავარი"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
index 2841af5..7f59d97 100644
--- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml
+++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi роумингін іздеулерге әрқашан рұқсат ету"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Бұрынғы DHCP клиентін пайдалану"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Ұялы деректер әрқашан белсенді"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Абсолютті дыбыс деңгейін өшіру"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Сымсыз дисплей растау опцияларын көрсету"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi жур. тір. дең. арт., Wi‑Fi желісін таңдағышта әр SSID RSSI бойынша көрсету"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Wi‑Fi сигналы әлсіз болғанда, деректер байланысы мәжбүрлі түрде ұялы желіге ауысады"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Бұл параметрлер жетілдіру мақсатында ғана қолданылады. Олар құрылғыңыз бен қолданбаларыңыздың бұзылуына немесе әдеттен тыс әрекеттерге себеп болуы мүмкін."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB арқылы орнатылған қолданбаларды растау"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT арқылы орнатылған қолданбалардың залалды болмауын тексеру."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Қолайсыз қатты дыбыс деңгейі немесе басқарудың болмауы сияқты қашықтағы құрылғыларда дыбыс деңгейімен мәселелер жағдайында Bluetooth абсолютті дыбыс деңгейі функциясын өшіреді."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Жергілікті терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Жергілікті шелл-код қол жетімділігін ұсынатын терминалды қолданбаны қосу"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP (жоғары кең жолақты сандық мазмұнды қорғау) тексеру"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсті түзету"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Әкімші өшірген"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Негізгі бет"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml
index 5f91309..a949538 100644
--- a/packages/SettingsLib/res/values-km-rKH/strings.xml
+++ b/packages/SettingsLib/res/values-km-rKH/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"តែងតែ​អនុញ្ញាត​​​ការវិភាគ​រ៉ូម​វ៉ាយហ្វាយ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ប្រើម៉ាស៊ីនកូន DHCP ចាស់"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ទិន្នន័យចល័តសកម្មជានិច្ច"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"បិទកម្រិតសំឡេងលឺខ្លាំង"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"បង្ហាញ​ជម្រើស​សម្រាប់​វិញ្ញាបនបត្រ​បង្ហាញ​ឥត​ខ្សែ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"បង្កើនកម្រិតកំណត់ហេតុវ៉ាយហ្វាយបង្ហាញក្នុង SSID RSSI ក្នុងកម្មវិធីជ្រើស​វ៉ាយហ្វាយ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ពេល​បាន​បើក វ៉ាយហ្វាយ​នឹង​កាន់តែ​បង្ខំ​ក្នុង​ការ​បញ្ជូន​ការ​ភ្ជាប់​ទិន្នន័យ​ទៅ​បណ្ដាញ​ចល័ត នៅ​ពេល​សញ្ញា​វ៉ាយហ្វាយ​យឺត"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ការ​កំណត់​ទាំង​នេះ​សម្រាប់​តែ​ការ​ប្រើ​ក្នុង​ការ​អភិវឌ្ឍ​ប៉ុណ្ណោះ។ ពួក​វា​អាច​ធ្វើ​ឲ្យ​ឧបករណ៍ និង​កម្មវិធី​របស់​អ្នក​ខូច ឬ​ដំណើរ​មិន​ត្រឹមត្រូវ។"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ផ្ទៀងផ្ទាត់​កម្មវិធី​តាម​យូអេសប៊ី"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ពិនិត្យ​កម្មវិធី​បាន​ដំឡើង​តាម​រយៈ ADB/ADT សម្រាប់​ឥរិយាបថ​ដែល​គ្រោះ​ថ្នាក់។"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"បិទលក្ខណៈពិសេសកម្រិតសំឡេងលឺខ្លាំងពេលភ្ជាប់ប៊្លូធូសក្នុងករណីមានបញ្ហាជាមួយឧបករណ៍បញ្ជាពីចម្ងាយ ដូចជាកម្រិតសំឡេងលឺខ្លាំងដែលមិនអាចទទួលយកបាន ឬខ្វះការគ្រប់គ្រង។"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ស្ថានីយ​មូលដ្ឋាន"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"បើក​កម្មវិធី​ស្ថានីយ​ដែល​ផ្ដល់​ការ​ចូល​សែល​មូលដ្ឋាន"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"ពិនិត្យ HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ការ​កែ​ពណ៌"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"លក្ខណៈ​នេះ​គឺ​ជា​ការ​ពិសោធន៍ ហើយ​អាច​ប៉ះពាល់​ការ​អនុវត្ត។"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅ​សល់​ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូត​ដល់​ពេញ"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិន​បញ្ចូលថ្ម"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រង"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"ដើម"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index f24bd08..bfe0c1e 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi ರೋಮ್ ಸ್ಕ್ಯಾನ್‌ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ಹಿಂದಿನ DHCP ಕ್ಲೈಂಟ್ ಬಳಸಿ"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ಸೆಲ್ಯುಲರ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್‌ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್‌ಲೆಸ್‌‌‌ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ಲಾಗಿಂಗ್ ಮಟ್ಟನ್ನು ಹೆಚ್ಚಿಸಿ, Wi‑Fi ಆಯ್ಕೆಯಲ್ಲಿ ಪ್ರತಿಯೊಂದು SSID RSSI ತೋರಿಸಿ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ಸಕ್ರಿಯಗೊಂಡರೆ, Wi‑Fi ಸಿಗ್ನಲ್ ದುರ್ಬಲವಾಗಿದ್ದರೂ ಕೂಡ, ಸೆಲ್ಯುಲರ್‌ಗೆ ಡೇಟಾ ಸಂಪರ್ಕವನ್ನು ಹಸ್ತಾಂತರಿಸುವಲ್ಲಿ Wi‑Fi ಹೆಚ್ಚು ಆಕ್ರಮಣಕಾರಿಯಾಗಿರುತ್ತದೆ"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ಈ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಅಭಿವೃದ್ಧಿಯ ಬಳಕೆಗೆ ಮಾತ್ರ. ಅವುಗಳು ನಿಮ್ಮ ಸಾಧನ ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌‌ಗಳಿಗೆ ಧಕ್ಕೆ ಮಾಡಬಹುದು ಅಥವಾ ಅವು ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರುವಂತೆ ಮಾಡಬಹುದು."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ಮೂಲಕ ಆಪ್‌ ಪರಿಶೀಲಿಸಿ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ಹಾನಿಮಾಡುವಂತಹ ವರ್ತನೆಗಾಗಿ ADB/ADT ಮೂಲಕ ಸ್ಥಾಪಿಸಲಾದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ರಿಮೋಟ್ ಸಾಧನಗಳೊಂದಿಗೆ ಒಪ್ಪಲಾಗದ ಜೋರಾದ ವಾಲ್ಯೂಮ್ ಅಥವಾ ನಿಯಂತ್ರಣದ ಕೊರತೆಯಂತಹ ವಾಲ್ಯೂಮ್ ಸಮಸ್ಯೆಗಳಂತಹ ಸಂದರ್ಭದಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್ ವೈಶಿಷ್ಟ್ಯವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಬಹುದು."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ಸ್ಥಳೀಯ ಟರ್ಮಿನಲ್"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"ಸ್ಥಳೀಯ ಶೆಲ್ ಪ್ರವೇಶವನ್ನು ಒದಗಿಸುವ ಟರ್ಮಿನಲ್ ಅಪ್ಲಿಕೇಶನ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ಪರೀಕ್ಷಿಸುವಿಕೆ"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ಬಣ್ಣದ ತಿದ್ದುಪಡಿ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"ಸುಮಾರು <xliff:g id="LEVEL">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ನಿರ್ವಾಹಕರಿಂದ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"ಮುಖಪುಟ"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ಹಿಂದೆ"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ಉಳಿದಿದೆ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index dc55956..5d1176a 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi 로밍 스캔 항상 허용"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"이전 DHCP 클라이언트 사용"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"모바일 데이터 항상 활성화"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"절대 볼륨 사용 안함"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"무선 디스플레이 인증서 옵션 표시"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi 로깅 수준을 높이고, Wi‑Fi 선택도구에서 SSID RSSI당 값을 표시합니다."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"사용 설정하면 Wi-Fi 신호가 약할 때 데이터 연결을 Wi-Fi에서 데이터 네트워크로 더욱 적극적으로 핸드오버합니다."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"이 설정은 개발자용으로만 설계되었습니다. 이 설정을 사용하면 기기 및 애플리케이션에 예기치 않은 중단이나 오류가 발생할 수 있습니다."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB를 통해 설치된 앱 확인"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT을 통해 설치된 앱에 유해한 동작이 있는지 확인"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"참기 어려울 정도로 볼륨이 크거나 제어가 되지 않는 등 원격 기기에서 볼륨 문제가 발생할 경우 블루투스 절대 볼륨 기능을 사용 중지합니다."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"로컬 터미널"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"로컬 셸 액세스를 제공하는 터미널 앱 사용"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP 확인"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"색보정"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 대략 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"관리자가 사용 중지함"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"홈"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index 4e3bfdb..f0867f5 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi Роуминг Скандоо мүмкүнчүлүгүнө ар дайым уруксат берилсин"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Эскирген DHCP кардарын колдонуу"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Уюлдук дайындар ар дайым активдүү"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үндүн абсолюттук деңгээли өчүрүлсүн"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Зымсыз дисплейди сертификатто мүмкүнчүлүктөрүн көргөзүү"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi Кармагычта Wi‑Fi протокол деңгээлин жогорулатуу жана ар бир SSID RSSI үчүн көрсөтүү."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Иштетилгенде, Wi-Fi байланышы үзүл-кесил болуп жатканда, Wi-Fi дайындарды уюктук операторго өжөрлүк менен өткөрөт."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Бул орнотуулар өндүрүүчүлөр үчүн гана берилген. Булар түзмөгүңүздүн колдонмолорун бузулушуна же туура эмес иштешине алып келиши мүмкүн."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB аркылуу келген колдонмолорду ырастоо"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT аркылуу орнотулган колдонмолорду зыянкечтикке текшерүү."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Алыскы түзмөктөр өтө катуу добуш чыгарып же көзөмөлдөнбөй жатса Bluetooth \"Үндүн абсолюттук деңгээли\" функциясын өчүрөт."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Жергиликтүү терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Жергиликтүү буйрук кабыгын сунуштаган терминалга уруксат берүү"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP текшерүү"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Колдонмолор негизги жикте узак иш-аракеттерди аткарганда экран жаркылдасын"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Көрсөткүчтүн жайгшкн жери"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Учурдагы басылган дайндрд көрсөтүүчү экран катмары"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Таптоолорду көрсөтүү"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Экранда тапталган жерлерди көрсөтүү"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Экран жаңыруусун көрсөтүү"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Экран жаңырганда аны бүт бойдон жарык кылуу"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU көрүнүш жаңыртуулары"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Эркин формадагы терезелерди түзүү боюнча сынамык функцияны иштетүү"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Компүтердеги бэкаптын сырсөзү"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Компүтердеги толук бэкап учурда корголгон эмес"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Иш тактасынын камдалган сырсөзүн өзгөртүү же алып салуу үчүн таптап коюңуз"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Жаңы бэкапка сырсөз коюулду"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Жаңы сырсөз жана анын ырастоосу дал келген жок"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Жаңы бэкапка сырсөз коюлган жок"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Санарип мазмун үчүн оптималдаштырылган түстөр"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Иштебеген колдонмолор"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Иштеген жок. Которуштуруу үчүн таптап коюңуз."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Иштеп турат. Которуштуруу үчүн таптап коюңуз."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Иштеп жаткан кызматтар"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Учурда иштеп жаткан кызматтарды көрүү жана көзөмөлдөө"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Түнкү режим"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсүн тууралоо"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - болжол менен <xliff:g id="TIME">%2$s</xliff:g> саат калды"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> толгончо"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Администратор өчүрүп койгон"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Башкы бет"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml
index 0e3eebd..1419466 100644
--- a/packages/SettingsLib/res/values-lo-rLA/strings.xml
+++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ອະ​ນຸ​ຍາດ​ການ​ສະ​ແກນ​ການ​ໂຣມ Wi‑Fi ​ສະ​ເໝີ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ໃຊ້​ລູກ​ຄ້າ DHCP ຕຳ​ນານ"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ຂໍ້​ມູນ​ມື​ຖື​ເປີດ​ຢູ່​ສະ​ເໝີ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ປິດໃຊ້ລະດັບສຽງສົມບູນ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ສະແດງໂຕເລືອກສຳລັບການສະແດງການຮັບຮອງລະບົບໄຮ້ສາຍ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"ເພີ່ມ​ລະ​ດັບ​ການ​ເກັບ​ປະ​ຫວັດ Wi‑Fi, ສະ​ແດງ​ຕໍ່ SSID RSSI ​ໃນ​ Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ເມື່ອ​ເປີດ​ນຳ​ໃຊ້​ແລ້ວ, ເຄືອ​ຂ່າຍ Wi-Fi ຈະ​ຖືກ​ປ່ຽນ​ໄປ​ໃຊ້​ເຄືອ​ຂ່າຍ​ໂທ​ລະ​ສັບ​ແທນ​ຫາກ​ສັນ​ຍານ Wi-Fi ອ່ອນ"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ການ​ຕັ້ງຄ່າ​ເຫຼົ່ານີ້​ແມ່ນ​ມີ​ຈຸດປະສົງ​ເພື່ອ​ການ​ພັດທະນາ​ເທົ່ານັ້ນ. ພວກ​ມັນ​ສາມາດ​ເຮັດ​ໃຫ້​ອຸປະກອນ ແລະ​ແອັບພລິເຄຊັນ​ຂອງ​ທ່ານ​ຢຸດ​ເຮັດ​ວຽກ ຫຼື​ເຮັດ​ວຽກ​ຜິດປົກກະຕິ​ໄດ້."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ຢືນຢັນແອັບຯຜ່ານທາງ USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ກວດສອບແອັບຯທີ່ຕິດຕັ້ງແລ້ວຜ່ານທາງ ADB/ADT ເພື່ອກວດຫາພຶດຕິກຳທີ່ເປັນອັນຕະລາຍ."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ປິດໃຊ້ຄຸນສົມບັດລະດັບສຽງສົມບູນຂອງ Bluetooth ໃນກໍລະນີເກີດບັນຫາລະດັບສຽງສົມບູນກັບອຸປະກອນທາງໄກ ເຊັ່ນວ່າ ລະດັບສຽງດັງເກີນຍອມຮັບໄດ້ ຫຼື ຄວບຄຸມບໍ່ໄດ້."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal ໃນໂຕເຄື່ອງ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"ເປີດນຳໃຊ້ແອັບຯ Terminal ທີ່ໃຫ້ການເຂົ້າເຖິງ shell ໃນໂຕເຄື່ອງໄດ້"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"ການກວດສອບ HDCP"</string>
@@ -251,7 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"ເປີດໃຊ້ການຮອງຮັບໜ້າຕ່າງຮູບແບບອິດສະຫຼະທີ່ທົດລອງໃຊ້."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນເດັກສະທັອບ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ການ​ສຳຮອງ​ຂໍ້ມູນ​ເຕັມຮູບແບບ​ໃນ​ເດັກສະທັອບ​ຍັງ​ບໍ່​ໄດ້​ຮັບ​ການ​ປ້ອງກັນ​ໃນ​ເວລາ​ນີ້"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ແຕະເພື່ອປ່ຽນ ຫຼືລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັສທັອບ"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ແຕະເພື່ອປ່ຽນ ຫຼືລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັກສະທັອບ"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"ຕັ້ງລະຫັດສຳຮອງໃໝ່ແລ້ວ"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"ລະຫັດຜ່ານໃໝ່ ແລະລະຫັດຢືນຢັນບໍ່ກົງກັນ"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"ການຕັ້ງລະຫັດສຳຮອງຂໍ້ມູນລົ້ມເຫລວ"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ການ​ປັບ​ແຕ່ງ​ສີ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"​ຄຸນ​ສົມ​ບັດ​ນີ້​ກຳ​ລັງ​ຢູ່​ໃນ​ການ​ທົດ​ລອງ​ແລະ​ອາດ​ມີ​ຜົນ​ຕໍ່​ປະ​ສິດ​ທິ​ພາບ."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ​ເຫຼືອປະ​ມານ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງ​ຈະ​ເຕັມ"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ຖືກປິດໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"​ໜ້າຫຼັກ"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 109fa09..3f5493d 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Visada leisti „Wi-Fi“ tarptiklinio ryšio nuskaitymą"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Naudoti seną DHCP kliento programą"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Korinio ryšio duomenys visada aktyvūs"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Išjungti didžiausią garsą"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rodyti belaidžio rodymo sertifikavimo parinktis"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Padidinti „Wi‑Fi“ įrašymo į žurnalą lygį, rodyti SSID RSSI „Wi-Fi“ rinkiklyje"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Jei įgalinta ši parinktis, „Wi‑Fi“ agresyviau perduos duomenų ryšį į mobiliojo ryšio tinklą, kai „Wi‑Fi“ signalas bus silpnas"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Šie nustatymai skirti tik kūrėjams. Nustačius juos įrenginys ir jame naudojamos programos gali nustoti veikti arba veikti netinkamai."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Patvirtinti progr. naudojant USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Patikrinkite, ar programų, įdiegtų naudojant ADB / ADT, veikimas nėra žalingas."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Išjungiama „Bluetooth“ didžiausio garso funkcija, jei naudojant nuotolinio valdymo įrenginius kyla problemų dėl garso, pvz., garsas yra per didelis arba jo negalima tinkamai valdyti."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Vietinis terminalas"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Įgal. terminalo progr., siūlančią prieigą prie viet. apvalkalo"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP tikrinimas"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Ekr. blyksės, kai pr. atl. ilgus proc. pgr. gijoje"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Žymiklio vieta"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Ekrano perdanga rodo dabartinius lietimo duomenis"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Rodyti palietimus"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Rodyti vaizdinius palietimų atsiliepimus"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Rodyti paviršiaus naujin."</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Naujinant mirginti visus langų paviršius"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Rodyt GPU rodinių naujin."</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Įgalinamas eksperimentinių laisvos formos langų palaikymas."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Viet. atsrg. kop. slapt."</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Šiuo metu visos vietinės atsarginės kopijos neapsaugotos"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Jei norite pakeisti ar pašalinti visų stalinio kompiuterio atsarginių kopijų slaptažodį, palieskite"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nustatytas naujas atsarginės kopijos slaptažodis"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Naujas slaptažodis ir patvirtinimas neatitinka"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Nustatant atsarginės kopijos slaptažodį įvyko klaida"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Skaitmeniniam turiniui optimizuotos spalvos"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Neaktyvios programos"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Neaktyvi. Palieskite, kad perjungtumėte."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktyvi. Palieskite, kad perjungtumėte."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Vykdomos paslaugos"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Žiūrėti ir valdyti dabar vykdomas paslaugas"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Naktinis režimas"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Spalvų taisymas"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Išjungė administratorius"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Pagrindinis ekranas"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 9a5483e..dd70703 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vienmēr atļaut Wi‑Fi meklēšanu"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Lietot mantoto DHCP klientu"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Vienmēr aktīvs mobilo datu savienojums"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Atspējot absolūto skaļumu"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Rādīt bezvadu attēlošanas sertifikācijas iespējas"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Palieliniet Wi‑Fi reģistrēšanas līmeni; rādīt katram SSID RSSI Wi‑Fi atlasītājā."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Ja opcija ir iespējota un Wi‑Fi signāls ir vājš, datu savienojuma pāreja no Wi-Fi uz mobilo tīklu tiks veikta agresīvāk."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Šie iestatījumi ir paredzēti tikai izstrādei. To dēļ var tikt pārtraukta vai traucēta ierīces un lietojumprogrammu darbība."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificēt, ja instalētas no USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Pārbaudīt, vai lietotņu, kuru instalēšanai izmantots ADB/ADT, darbība nav kaitīga."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Atspējo Bluetooth absolūtā skaļuma funkciju skaļuma problēmu gadījumiem attālajās ierīcēs, piemēram, ja ir nepieņemami liels skaļums vai nav iespējas kontrolēt skaļumu."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Vietējā beigu lietotne"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Iespējot beigu lietotni, kurā piedāvāta vietējā čaulas piekļuve"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP pārbaude"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Zibsnīt ekrānu, ja liet. ilgi darbojas galv. pav."</string>
     <string name="pointer_location" msgid="6084434787496938001">"Rādītāja atrašanās vieta"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Ekrāna pārklājums ar aktuāliem pieskāriena datiem"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Rādīt pieskārienus"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Rādīt vizuālo reakciju pēc pieskārieniem"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Rādīt virsmas atjauninājumus WL: 294"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Atjaunināt visa loga virsmas, kad tās tiek atjauninātas WL: 294"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Rādīt GPU skat. atjaun."</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Iespējo eksperimentālo brīvās formas logu atbalstu."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Datora dublējuma parole"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Darbvirsmas pilnie dublējumi pašlaik nav aizsargāti."</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Pieskarieties, lai mainītu vai noņemtu paroli pilniem datora dublējumiem."</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Jaunā dublējuma parole ir iestatīta."</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Jaunā parole un apstiprinājums neatbilst."</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Iestatot dublējuma paroli, radās kļūme."</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Digitālajam saturam optimizētas krāsas"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Neaktīvās lietotnes"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Neaktīva. Pieskarieties, lai pārslēgtu."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktīva. Pieskarieties, lai pārslēgtu."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Aktīvie pakalpojumi"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Pašreiz darbojošos pakalpojumu skatīšana un vadība"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Nakts režīms"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Krāsu korekcija"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> — aptuvenais atlikušais laiks: <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Atspējojis administrators"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Sākums"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 17de45b..5bdfd01 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Секогаш дозволувај Wi‑Fi скенирање во роаминг"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Користете наследен клиент на DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Мобилниот интернет е секогаш активен"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Оневозможете апсолутна јачина на звук"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Покажи ги опциите за безжичен приказ на сертификат"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Зголеми Wi‑Fi ниво на пријавување, прикажи по SSID RSSI во Wi‑Fi бирач"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Кога е вклучено, Wi-Fi ќе биде поагресивно при предавање на поврзувањето со податоци на мобилната мрежа при слаб сигнал на Wi-Fi."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Овие подесувања се наменети само за употреба за развој. Тие може да предизвикаат уредот и апликациите во него да се расипат или да се однесуваат необично."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Потврди апликации преку УСБ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Провери апликации инсталирани преку ADB/ADT за штетно однесување."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Ја оневозможува карактеристиката за апсолутна јачина на звук преку Bluetooth во случај кога ќе настанат проблеми со далечинските уреди, како на пр., неприфатливо силен звук или недоволна контрола."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локален терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Овозможи апликација на терминал што овозможува локален пристап кон школка."</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Проверување HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Осветли екран при. долги операции на главна нишка"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Локација на покажувач"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Прекривката на екран ги покажува тековните податоци на допир"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Прикажувај допири"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Прикажи визуелни повратни информации за допири"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Прикажи ажурир. површина"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Осветли површ. на прозорци при нивно ажурирање"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Прикажи ажурир. со GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Овозможува поддршка за експериментални прозорци со слободна форма."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Резервна лозинка за работна површина"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Целосни резервни копии на работната површина кои во моментов не се заштитени"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Допрете за да се промени или отстрани лозинката за целосни резервни копии на работната површина"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Подесена нова лозинка на резервна копија"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Новата лозинка и потврдата не се исти"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Неуспешно подесување лозинка на резервна копија"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Оптимизирани бои за дигитална содржина"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Неактивни апликации"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Неактивно. Допрете за да смените."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Активно. Допрете за да смените."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Активни услуги"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Погледнете и контролирајте услуги што се моментално активни"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Ноќен режим"</string>
@@ -299,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција на боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостанува приближно <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна"</string>
@@ -314,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Целосна"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Оневозможено од администраторот"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Почетна страница"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Пред <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Преостанаа <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml
index 7df1cf3..38b4771 100644
--- a/packages/SettingsLib/res/values-ml-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"എപ്പോഴും വൈഫൈ റോം സ്‌‌കാൻ അനുവദിക്കൂ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"പഴയ DHCP ക്ലയന്റ് ഉപയോഗിക്കുക"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"സെല്ലുലാർ ഡാറ്റ എല്ലായ്‌പ്പോഴും സജീവം"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"അബ്‌സൊല്യൂട്ട് വോളിയം പ്രവർത്തനരഹിതമാക്കുക"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"വയർലെസ് ഡിസ്‌പ്ലേ സർട്ടിഫിക്കേഷനായി ഓപ്‌ഷനുകൾ ദൃശ്യമാക്കുക"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"വൈഫൈ പിക്കറിൽ ഓരോ SSID RSSI പ്രകാരം കാണിക്കാൻ വൈഫൈ ലോഗിംഗ് നില വർദ്ധിപ്പിക്കുക"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"പ്രവർത്തനക്ഷമമായിരിക്കുമ്പോൾ, വൈഫൈ സിഗ്‌നൽ കുറവായിരിക്കുന്ന സമയത്ത് സെല്ലുലാറിലേക്ക് ഡാറ്റ കണക്ഷൻ മുഖേന കൈമാറുന്നതിൽ വൈഫൈ കൂടുതൽ പ്രവർത്തനക്ഷമമാകും"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ഈ ക്രമീകരണങ്ങൾ വികസന ഉപയോഗത്തിന് മാത്രമായുള്ളതാണ്. അവ നിങ്ങളുടെ ഉപകരണവും അതിലെ അപ്ലിക്കേഷനുകളും തകരാറിലാക്കുന്നതിനോ തെറ്റായി പ്രവർത്തിക്കുന്നതിനോ ഇടയാക്കാം."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB വഴി ആപ്സ് പരിശോധിച്ചുറപ്പിക്കൂ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"കേടാക്കുന്ന പ്രവർത്തനരീതിയുള്ള ADB/ADT വഴി ഇൻസ്റ്റാളുചെയ്‌ത അപ്ലിക്കേഷനുകൾ പരിശോധിക്കുക."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"അസ്വീകാര്യമായ തരത്തിൽ ഉയർന്ന വോളിയമോ ശബ്ദ നിയന്ത്രണത്തിന്റെ അഭാവമോ പോലെ, വിദൂര ഉപകരണങ്ങളുമായി ബന്ധപ്പെട്ട വോളിയം പ്രശ്നങ്ങൾ ഉണ്ടാകുന്ന സാഹചര്യത്തിൽ, Bluetooth അബ്‌സൊല്യൂട്ട് വോളിയം ഫീച്ചർ പ്രവർത്തനരഹിതമാക്കുന്നു."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"പ്രാദേശിക ടെർമിനൽ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"പ്രാദേശിക ഷെൽ ആക്‌സസ് നൽകുന്ന ടെർമിനൽ അപ്ലിക്കേഷൻ പ്രവർത്തനക്ഷമമാക്കുക"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP പരിശോധന"</string>
@@ -266,8 +268,8 @@
     <item msgid="5363960654009010371">"ഡിജിറ്റൽ ഉള്ളടക്കത്തിനായി വർണ്ണങ്ങൾ ഒപ്റ്റിമൈസ് ചെയ്തു"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"നിഷ്‌ക്രിയ ആപ്പ്‌സ്"</string>
-    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"നിഷ്‌ക്രിയം. ടോഗിൾ ചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string>
-    <string name="inactive_app_active_summary" msgid="4174921824958516106">"സജീവം. ടോഗിൾ ചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string>
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"നിഷ്‌ക്രിയം. മാറ്റുന്നതിനു ടാപ്പുചെയ്യുക."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"സജീവം. മാറ്റുന്നതിന് ടാപ്പുചെയ്യുക."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"നിലവിൽ പ്രവർത്തിക്കുന്ന സേവങ്ങൾ കാണുക, നിയന്ത്രിക്കുക"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"നൈറ്റ് മോഡ്"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"വർണ്ണം ക്രമീകരിക്കൽ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"അഡ്‌മിനിസ്ട്രേറ്റർ പ്രവർത്തനരഹിതമാക്കി"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"ഹോം"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> മുമ്പ്"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml
index d4a3d44..3b5d5f1 100644
--- a/packages/SettingsLib/res/values-mn-rMN/strings.xml
+++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi Роум сканыг байнга зөвшөөрөх"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Хуучин DHCP харилцагчийг хэрэглэх"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Үүрэн холбооны датаг үргэлж идэвхтэй байлгана"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Үнэмлэхүй дууны түвшинг идэвхгүй болгох"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Утасгүй дэлгэцийн сертификатын сонголтыг харуулах"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi лог-н түвшинг нэмэгдүүлэх, Wi‑Fi Сонгогч дээрх SSID-д ногдох RSSI-г харуулах"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Идэвхжүүлсэн үед Wi‑Fi дохио сул бол дата холболтыг Үүрэн рүү шилжүүлэхдээ илүү идэвхтэй байх болно"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Эдгээр тохиргоо нь зөвхөн хөгжүүлэлтэд ашиглах зорилготой. Эдгээр нь таны төхөөрөмж буюу түүн дээрх аппликешнүүдийг эвдрэх, буруу ажиллах шалтгаан нь болж болно."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Апп-г USB-р тулгах"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT-р суулгасан апп-уудыг хорлонтой авиртай эсэхийг шалгах."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Хэт чанга дуугаралт эсвэл муу тохиргоо зэрэг алсын зайн төхөөрөмжийн дуугаралттай холбоотой асуудлын үед Bluetooth-ийн үнэмлэхүй дууны түвшинг идэвхгүй болго."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локал терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Локал суурьт хандалт хийх боломж олгодог терминалын апп-г идэвхжүүлэх"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP шалгах"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Өнгө тохируулах"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Админ идэвхгүй болгосон"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Нүүр"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 6a2bd61..493f579 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाय-फाय रोम स्‍कॅनला नेहमी अनुमती द्या"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"परंपरागत DHCP क्लायंटचा वापर करा"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"सेल्युलर डेटा नेहमी सक्रिय"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"संपूर्ण आवाज अक्षम करा"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"वायरलेस प्रदर्शन प्रमाणिकरणासाठी पर्याय दर्शवा"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाय-फाय लॉगिंग स्‍तर वाढवा, वाय-फाय निवडकामध्‍ये प्रति SSID RSSI दर्शवा"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"सक्षम केल्यास, वाय-फाय सिग्‍नल निम्‍न असताना, वाय-फाय डेटा कनेक्‍शन सेल्‍युलरवर बळपूर्वक स्विच करेल."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"या सेटिंग्जचा हेतू फक्त विकास करण्याच्या वापरासाठी आहे. त्यामुळे आपले डिव्हाइस आणि त्यावरील अनुप्रयोग विघटित होऊ शकतात किंवा गैरवर्तन करू शकतात."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB वरील अॅप्स सत्यापित करा"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानीकारक वर्तनासाठी ADB/ADT द्वारे स्थापित अॅप्स तपासा."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"दूरस्थ डिव्हाइसेसमध्ये सहन न होणारा मोठा आवाज किंवा नियंत्रणचा अभाव यासारखी आवाजाची समस्या असल्यास ब्लूटुथ संपूर्ण आवाज वैशिष्ट्य अक्षम करते."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"स्थानिक टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"स्थानिक शेल प्रवेश देणारा टर्मिनल अॅप सक्षम करा"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP तपासणी"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"मुख्य थ्रेडवर अॅप्स मोठी कार्ये करतात तेव्हा स्क्रीन फ्लॅश करा"</string>
     <string name="pointer_location" msgid="6084434787496938001">"पॉइंटर स्थान"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"वर्तमान स्पर्श डेटा दर्शविणारे स्क्रीन आच्छादन"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"टॅप दर्शवा"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"टॅपसाठी दृश्यमान अभिप्राय दर्शवा"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"पृष्ठभाग अद्यतने दर्शवा"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"संपूर्ण विंडो पृष्ठभाग अद्ययावत होतात तेव्हा ते फ्‍लॅश करा"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU दृश्य अद्यतने दर्शवा"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"प्रायोगिक मुक्तस्वरूपाच्या विंडोसाठी समर्थन सक्षम करते."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"डेस्कटॉप बॅकअप संकेतशब्द"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला संकेतशब्द बदलण्यासाठी किंवा काढण्यासाठी टॅप  करा"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"नवीन बॅक अप संकेतशब्द सेट झाला"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"नवीन संकेतशब्द आणि पुष्टीकरण जुळत नाही"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"बॅक अप संकेतशब्द सेट करणे अयशस्वी"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"डिजिटल सामग्रीसाठी ऑप्टिमाइझ केलेले रंग"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"निष्क्रिय अ‍ॅप्स"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"निष्क्रिय. टॉगल करण्यासाठी टॅप करा."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"सक्रिय. टॉगल करण्यासाठी टॅप करा."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"चालू सेवा"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"सध्या चालत असलेल्या सेवा पहा आणि नियंत्रित करा"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"रात्र मोड"</string>
@@ -299,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रंग सुधारणा"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्‍ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण होण्यात"</string>
@@ -314,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"प्रशासकाद्वारे अक्षम केलेले"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"मुख्यपृष्ठ"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पूर्वी"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> शिल्लक"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml
index 42e9ddd..0509159 100644
--- a/packages/SettingsLib/res/values-ms-rMY/strings.xml
+++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sentiasa benarkan Imbasan Perayauan Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Gunakan pelanggan DHCP lama"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Data selular sentiasa aktif"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Lumpuhkan kelantangan mutlak"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Apabila didayakan, Wi-Fi akan menjadi lebih agresif dalam menyerahkan sambungan data ke Selular, apabila isyarat Wi-Fi rendah"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Tetapan ini adalah untuk penggunaan pembangunan sahaja. Peranti dan aplikasi yang terdapat padanya boleh rosak atau tidak berfungsi dengan betul."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Sahkan apl melalui USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Semak apl yang dipasang melalui ADB/ADT untuk tingkah laku yang berbahaya."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Lumpuhkan ciri kelantangan mutlak Bluetooth dalam kes isu kelantangan menggunakan peranti kawalan jauh seperti kelantangan yang sangat kuat atau tidak dapat mengawal."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal setempat"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Dayakan apl terminal yang menawarkan akses shell tempatan"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Penyemakan HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Kelip skrin apabila apl beroperasi lama pada urutan utama"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Lokasi penuding"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Tindihan skrin menunjukkan data sentuh semasa"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Tunjukkan ketikan"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Tunjukkan maklum balas visual untuk ketikan"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Tunjuk kemas kini permukaan"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Denyar permukaan tetingkap apabila dikemas kini"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Tunjuk kemas kini GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Mendayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Kata laluan sandaran komputer meja"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Sandaran penuh komputer meja tidak dilindungi pada masa ini"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Kata laluan sandaran baharu telah ditetapkan"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Kata laluan baharu dan pengesahan tidak sepadan"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Gagal menetapkan kata laluan sandaran"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Warna dioptimumkan untuk kandungan digital"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Apl yang tidak aktif"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Ketik untuk menogol."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Ketik untuk menogol."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Perkhidmatan dijalankan"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Lihat dan kawal perkhidmatan yang sedang dijalankan"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Mod malam"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pembetulan warna"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira. <xliff:g id="TIME">%2$s</xliff:g> yang tinggal"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dilumpuhkan oleh pentadbir"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Skrin Utama"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml
index bace8b6..9f56479 100644
--- a/packages/SettingsLib/res/values-my-rMM/strings.xml
+++ b/packages/SettingsLib/res/values-my-rMM/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi ရွမ်းရှာဖွေမှုကို အမြဲတမ်း ခွင့်ပြုမည်"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"DHCP ကလိုင်းယင့် အဟောင်းအားသုံးရန်"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ဆဲလ်လူလာဒေတာ အမြဲတမ်းဖွင့်ထားသည်"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ပကတိ အသံနှုန်း သတ်မှတ်ချက် ပိတ်ရန်"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ကြိုးမဲ့ အခင်းအကျင်း အသိအမှတ်ပြုလက်မှတ်အတွက် ရွေးချယ်စရာများပြရန်"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi မှတ်တမ်းတင်ခြင်း နှုန်းအားမြင့်ကာ၊ Wi‑Fi ရွေးရာတွင် SSID RSSI ဖြင့်ပြပါ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ဖွင့်ထားလျှင်၊ Wi‑Fi မှ ဆယ်လူလာသို့ အချက်လက် ချိတ်ဆက်မှုအား လွှဲပြောင်းရာ၌ ပိုမိုထိရောက်ပါသည်၊ WIFI အားနည်းနေချိန်တွင်"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ဤဆက်တင်းများကို တည်ဆောက်ပြုပြင်ရာတွင် သုံးရန်အတွက်သာ ရည်ရွယ်သည်။ ၎င်းတို့သည် သင်၏စက်နှင့် အပလီကေးရှင်းများကို ရပ်စေခြင်း သို့ လုပ်ဆောင်ချက်မမှန်ကန်ခြင်းများ ဖြစ်ပေါ်စေနိုင်သည်။"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USBပေါ်မှ အပလီကေးရှင်းများကို အတည်ပြုစိစစ်ရန်"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT မှတဆင့် ထည့်သွင်းသော အပလီကေးရှင်းများကို အန္တရာယ်ဖြစ်နိုင်ခြင်း ရှိမရှိ စစ်ဆေးရန်။"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ချိတ်ဆက်ထားသည့် ကိရိယာတွင် လက်မခံနိုင်လောက်အောင် ဆူညံ သို့မဟုတ် ထိန်းညှိမရနိုင်သော အသံပိုင်းပြဿနာ ရှိခဲ့လျှင် ဘလူးတုသ် ပကတိ အသံနှုန်းကို ပိတ်ပါ။"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"လိုကယ်တာမီနယ်"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"local shell အသုံးပြုခွင့်ကမ်းလှမ်းသော တာမင်နယ်အပလီကေးရှင်းဖွင့်ပါ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP စစ်ဆေးမှု"</string>
@@ -251,7 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"စမ်းသပ်မှု အခမဲ့ပုံစံ ဝင်းဒိုးများအတွက် ပံ့ပိုးမှုကို ဖွင့်ပါ။"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Desktop အရန်စကားဝှက်"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"အလုပ်ခုံတွင် အရန်သိမ်းဆည်းခြင်းများကို လောလောဆယ် မကာကွယ်နိုင်ပါ။"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"အလုပ်ခုံစက် အပြည့်အဝအရံကူးထားရန်အတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"စားပွဲတင်ကွန်ပျူတာကို အပြည့်အဝအရံကူးထားရန်အတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"အရန်သိမ်းဆည်းခြင်းအတွက် စကားဝှက်အသစ်ကို သတ်မှတ်ပြီးပြီ။"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"စကားဝှက်အသစ်နှင့် အတည်ပြုချက် ကွဲလွဲနေသည်။"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"အရန်သိမ်းဆည်းခြင်းအတွက် စကားဝှက်သတ်မှတ်ချက် မအောင်မြင်ပါ။"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"အရောင်ပြင်ဆင်မှု"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဒီအင်္ဂါရပ်မှာ စမ်းသပ်မှု ဖြစ်၍ လုပ်ကိုင်မှုကို အကျိုးသက်ရောက်နိုင်သည်။"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ခန့်မှန်းခြေ။ <xliff:g id="TIME">%2$s</xliff:g> ကျန်ရှိနေ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> အပြည့်အထိ"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"စီမံခန့်ခွဲသူမှ ပိတ်ထားသည်"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"ပင်မ"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 6843839..013fe26 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillat alltid skanning for Wi-Fi-roaming"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Bruk eldre DHCP-klient"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobildata er alltid aktiv"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Slå av funksjonen for absolutt volum"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Vis alternativer for sertifisering av trådløs skjerm"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Øk Wi-Fi-loggenivå – vis per SSID RSSI i Wi-Fi-velgeren"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Hvis dette slås på, overfører Wi-Fi-nettverket datatilkoblingen til mobil mer aggressivt når Wi-Fi-signalet er lavt"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Disse innstillingene er bare beregnet for bruk under programutvikling. De kan forårsake problemer med enheten din og tilhørende apper."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Bekreft apper via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Sjekk apper som er installert via ADB/ADT for skadelig adferd."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Slår av funksjonen for absolutt volum via Bluetooth i tilfelle det oppstår volumrelaterte problemer med eksterne enheter, for eksempel uakseptabelt høyt volum eller mangel på kontroll."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktiver terminalappen som gir lokal kommandolistetilgang"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-kontroll"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Skjermblink ved lange apphandlinger på hovedtråd"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Pekerplassering"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Skjermoverlegg viser aktuelle berøringsdata"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Vis trykk"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Vis visuell tilbakemelding for trykk"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Vis overflateoppdateringer"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Fremhev hele vindusoverflater når de oppdateres"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Vis GPU-visningsoppdateringer"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Slår på støtte for vinduer i eksperimentelt fritt format."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Passord for sikkerhetskopiering på datamaskin"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Fullstendig sikkerhetskopiering på datamaskin beskyttes ikke for øyeblikket."</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Trykk for å endre eller fjerne passordet for fullstendige sikkerhetskopier på datamaskinen"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Nytt passord for sikkerhetskopiering er angitt."</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Gjentakelsen av passordet er ikke identisk med det første du skrev inn"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Kunne ikke angi nytt passord for sikkerhetskopiering"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Farger som er optimalisert for digitalt innhold"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Inaktive apper"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Ikke aktiv. Trykk for å slå av/på."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktiv. Trykk for å slå av/på."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Aktive tjenester"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Se og kontrollér tjenester som kjører for øyeblikket"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Nattmodus"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Fargekorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funksjonen er eksperimentell og kan påvirke ytelsen."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> igjen"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Avslått av administratoren"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Startside"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index a5fd194..715f055 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"वाइफाइ घुम्ने स्क्यान गर्न सधैँ अनुमति दिनुहोस्"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"लिगेसी DHCP ग्राहक प्रयोग गर्नुहोस्"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"सेलुलर डेटा सधैं सक्रिय"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"निरपेक्ष आवाज असक्षम गर्नुहोस्"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ताररहित प्रदर्शन प्रमाणीकरणका लागि विकल्पहरू देखाउनुहोस्"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"वाइफाइ लग स्तर बढाउनुहोस्, वाइफाइ चयनकर्तामा प्रति SSID RSSI देखाइन्छ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"वाइफाइ संकेत कम हुँदा, सक्षम जब गरिन्छ, वाइफाइ सेलुलर लागि डेटा जडान सुम्पनामा बढी आक्रामक हुनेछ"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"यी सेटिङहरू केवल विकास प्रयोगको लागि विचार गरिएको हो। तिनीहरूले तपाईंको उपकरण र अनुप्रयोगहरूलाई विच्छेदन गर्न वा दुर्व्यवहार गर्न सक्दछ।"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB मा अनुप्रयोगहरू रुजु गर्नुहोस्"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"हानिकारक व्यवहारको लागि ADB/ADT को माध्यमबाट स्थापित अनुप्रयोगहरूको जाँच गर्नुहोस्।"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"रिमोट यन्त्रहरूमा अस्वीकार्य चर्को आवाज वा नियन्त्रणमा कमी जस्ता आवाज सम्बन्धी समस्याहरूको अवस्थामा ब्लुटुथ निरपेक्ष आवाज सुविधालाई असक्षम गराउँछ।"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"स्थानीय टर्मिनल"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"स्थानीय सेल पहुँच प्रदान गर्ने टर्मिनल अनुप्रयोग सक्षम गर्नुहोस्"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP जाँच गर्दै"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"रङ्ग सुधार"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%2$s</xliff:g> बाँकी छ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग। <xliff:g id="TIME">%2$s</xliff:g> बायाँ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण नभए सम्म"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"प्रशासकद्वारा असक्षम गरिएको"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"गृह"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> पहिले"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> बाँकी"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 99c0932..bd24201 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Altijd roamingscans voor wifi toestaan"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Oude DHCP-client gebruiken"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobiele gegevens altijd actief"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Absoluut volume uitschakelen"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Opties weergeven voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Logniveau voor wifi verhogen, weergeven per SSID RSSI in wifi-kiezer"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Indien ingeschakeld, is wifi agressiever bij het overgeven van de gegevensverbinding aan mobiel wanneer het wifi-signaal zwak is"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Deze instellingen zijn uitsluitend bedoeld voor ontwikkelingsgebruik. Je apparaat en apps kunnen hierdoor vastlopen of anders reageren."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Apps verifiëren via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Apps die zijn geïnstalleerd via ADB/ADT, controleren op schadelijk gedrag"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Hiermee wordt de functie voor absoluut volume van Bluetooth uitgeschakeld in geval van volumeproblemen met externe apparaten, zoals een onacceptabel hoog volume of geen volumeregeling."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokale terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Terminal-app inschakelen die lokale shell-toegang biedt"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-controle"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Kleurcorrectie"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ca. <xliff:g id="TIME">%2$s</xliff:g> resterend"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Uitgeschakeld door beheerder"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Startpagina"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml
index 407ec95..f9c0c11 100644
--- a/packages/SettingsLib/res/values-pa-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ਹਮੇਸ਼ਾਂ Wi‑Fi Roam Scans ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ਲੀਗੇਸੀ DHCP ਕਲਾਈਂਟ ਵਰਤੋ"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ਸੈਲਿਊਲਰ ਡੇਟਾ ਹਮੇਸ਼ਾ ਕਿਰਿਆਸ਼ੀਲ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ਪੂਰਨ ਵੌਲਯੂਮ ਨੂੰ ਅਯੋਗ ਬਣਾਓ"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ ਲਈ ਚੋਣਾਂ ਦਿਖਾਓ"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ਲੌਗਿੰਗ ਪੱਧਰ ਵਧਾਓ, Wi‑Fi Picker ਵਿੱਚ ਪ੍ਰਤੀ SSID RSSI ਦਿਖਾਓ"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ਜਦੋਂ ਸਮਰਥਿਤ ਹੋਵੇ, ਤਾਂ Wi‑Fi ਸੈਲਿਊਲਰ ਨੂੰ ਡਾਟਾ ਕਨੈਕਸ਼ਨ ਹੈਂਡ ਓਵਰ ਕਰਨ ਵਿੱਚ ਵੱਧ ਅਗ੍ਰੈਸਿਵ ਹੋ ਜਾਏਗਾ, ਜਦੋਂ Wi‑Fi ਸਿਗਨਲ ਘੱਟ ਹੋਵੇ"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ਇਹ ਸੈਟਿੰਗਾਂ ਕੇਵਲ ਵਿਕਾਸਕਾਰ ਦੀ ਵਰਤੋਂ ਲਈ ਹਨ। ਇਹ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਅਤੇ ਇਸਤੇ ਮੌਜੂਦ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਬ੍ਰੇਕ ਕਰਨ ਜਾਂ ਦੁਰਵਿਵਹਾਰ ਕਰਨ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦੇ ਹਨ।"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ਤੇ ਐਪਸ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ਹਾਨੀਕਾਰਕ ਵਿਵਹਾਰ ਲਈ ADB/ADT ਰਾਹੀਂ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ਰਿਮੋਟ ਡੀਵਾਈਸਾਂ ਨਾਲ ਵੌਲਯੂਮ ਸਮੱਸਿਆਵਾਂ ਜਿਵੇਂ ਕਿ ਨਾ ਪਸੰਦ ਕੀਤੀ ਜਾਣ ਵਾਲੀ ਉੱਚੀ ਵੌਲਯੂਮ ਜਾਂ ਕੰਟਰੋਲ ਦੀ ਕਮੀ ਵਰਗੀ ਹਾਲਤ ਵਿੱਚ ਬਲੂਟੁੱਥ ਪੂਰਨ ਵੌਲਯੂਮ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਅਯੋਗ ਬਣਾਉਂਦਾ ਹੈ।"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"ਸਥਾਨਕ ਟਰਮੀਨਲ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"ਟਰਮੀਨਲ ਐਪ ਨੂੰ ਸਮਰੱਥ ਬਣਾਓ ਜੋ ਸਥਾਨਕ ਸ਼ੈਲ ਪਹੁੰਚ ਆੱਫਰ ਕਰਦਾ ਹੈ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP ਜਾਂਚ"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"ਰੰਗ ਸੰਸ਼ੋਧਨ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> ਪਹਿਲਾਂ"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> ਬਾਕੀ"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 9902ad7..4ff0d03 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Zawsze szukaj Wi-Fi w roamingu"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Użyj starszego klienta DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dane komórkowe zawsze aktywne"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Wyłącz głośność bezwzględną"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaż opcje certyfikacji wyświetlacza bezprzewodowego"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zwiększ poziom rejestrowania Wi‑Fi, pokazuj według RSSI SSID w selektorze Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Po włączeniu połączenie danych będzie bardziej agresywnie przełączać się z Wi-Fi na sieć komórkową przy słabym sygnale Wi-Fi"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Te ustawienia są przeznaczone wyłącznie dla programistów. Ich użycie może spowodować uszkodzenie lub nieprawidłowe działanie urządzenia i zainstalowanych na nim aplikacji."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Zweryfikuj aplikacje przez USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Sprawdź, czy aplikacje zainstalowane przez ADB/ADT nie zachowują się w szkodliwy sposób"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Wyłącza funkcję Głośność bezwzględna Bluetooth, jeśli występują problemy z urządzeniami zdalnymi, np. zbyt duża głośność lub brak kontroli."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal lokalny"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Włącz terminal, który umożliwia dostęp do powłoki lokalnej"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Sprawdzanie HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korekcja kolorów"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało ok. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Wyłączone przez administratora"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Ekran główny"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 923482b..b4251a5 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usar cliente DHCP legado"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dados da rede celular sempre ativos"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Quando ativada, o Wi-Fi será mais agressivo em transferir a conexão de dados para celular, quando o sinal de Wi-Fi estiver fraco"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Essas configurações são destinadas apenas para o uso de desenvolvedores. Elas podem causar a desativação ou mau funcionamento do dispositivo e dos apps contidos nele."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar apps por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Verificar comportamento nocivo em apps instalados via ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desativa o recurso Bluetooth de volume absoluto em caso de problemas com o volume em dispositivos remotos, como volume excessivamente alto ou falta de controle."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Ativar o app terminal que oferece acesso ao shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Verificação HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desativada pelo administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Início"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 840bd41..3dd9561 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Permitir sempre a deteção de Wi-Fi em roaming"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Utilizar cliente DHCP antigo"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dados móveis sempre ativados"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções da certificação de display sem fios"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Se estiver ativado, o Wi-Fi será mais agressivo ao transmitir a lig. de dados p/ a rede móvel quando o sinal Wi-Fi estiver fraco"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Estas definições destinam-se apenas a programação. Podem fazer com que o seu aparelho e as aplicações nele existentes falhem ou funcionem mal."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar aplicações de USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Verificar as aplicações instaladas via ADB/ADT para detetar comportamento perigoso."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desativa a funcionalidade de volume absoluto do Bluetooth caso existam problemas de volume com dispositivos remotos, como um volume insuportavelmente alto ou a ausência de controlo."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Ativar aplicação terminal que oferece acesso local à shell"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Verificação HDCP"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção da cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) aprox. <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desativado pelo administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Página inicial"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Há <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Resta(m) <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 923482b..b4251a5 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Sempre permitir verif. de roaming de Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Usar cliente DHCP legado"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dados da rede celular sempre ativos"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Desativar volume absoluto"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Mostrar opções de certificação de Display sem fio"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Aumentar o nível de registro do Wi-Fi; mostrar conforme o RSSI de SSID na Seleção de Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Quando ativada, o Wi-Fi será mais agressivo em transferir a conexão de dados para celular, quando o sinal de Wi-Fi estiver fraco"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Essas configurações são destinadas apenas para o uso de desenvolvedores. Elas podem causar a desativação ou mau funcionamento do dispositivo e dos apps contidos nele."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificar apps por USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Verificar comportamento nocivo em apps instalados via ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Desativa o recurso Bluetooth de volume absoluto em caso de problemas com o volume em dispositivos remotos, como volume excessivamente alto ou falta de controle."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminal local"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Ativar o app terminal que oferece acesso ao shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Verificação HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Correção de cor"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Desativada pelo administrador"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Início"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 02cc80e..e883d0a 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Se permite întotdeauna scanarea traficului Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Folosiți vechiul client DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Conexiunea de date mobile este întotdeauna activată"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Dezactivați volumul absolut"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Afișați opțiunile pentru certificarea Ecran wireless"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Măriți niv. de înr. prin Wi‑Fi, afișați în fcț. de SSID RSSI în Selectorul Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Când este activată, funcția Wi-Fi va fi mai agresivă la predarea conexiunii de date către mobil când semnalul Wi-Fi este slab"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Aceste setări sunt destinate exclusiv utilizării pentru dezvoltare. Din cauza lor, este posibil ca dispozitivul dvs. și aplicațiile de pe acesta să nu mai funcţioneze sau să funcţioneze necorespunzător."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verificați aplicațiile prin USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Verificați aplicațiile instalate utilizând ADB/ADT, pentru a detecta un comportament dăunător."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Dezactivează funcția Bluetooth de volum absolut în cazul problemelor de volum apărute la dispozitivele la distanță, cum ar fi volumul mult prea ridicat sau lipsa de control asupra acestuia."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Aplicație terminal locală"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Activați aplicația terminal care oferă acces la shell local"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Verificare HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Corecția culorii"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Dezactivată de administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Ecranul principal"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 57d2883..0f4eaa1 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Всегда включать поиск сетей Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Использовать устаревший DHCP-клиент"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Не отключать передачу данных"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Отключить абсолютный уровень громкости"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показывать параметры сертификации беспроводных мониторов"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"При выборе Wi‑Fi указывать в журнале RSSI для каждого SSID"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Принудительно переключаться на мобильную сеть, если сигнал Wi-Fi слабый"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Только для разработчиков. Изменение этих настроек может привести к сбоям или неправильной работе устройства и приложений."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Установка через USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Проверка безопасности приложений, устанавливаемых через ADB/ADT"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Отключить абсолютный уровень громкости Bluetooth при возникновении проблем на удаленных устройствах, например при слишком громком звучании или невозможности контролировать настройку."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локальный терминальный доступ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Разрешить терминальный доступ к локальной оболочке"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Проверка HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Подсвечивать экран во время длительных операций"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Отображать касания"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Визуализировать на экране нажатия и жесты"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Визуальный отклик"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Показывать места нажатия на экране"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Показ. обнов. поверхности"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Подсвечивать окна полностью при их обновлении"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Показывать обнов. экрана"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Включить экспериментальную функцию создания окон произвольной формы"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Пароль для резервного копирования"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Полные резервные копии в настоящее время не защищены"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Нажмите, чтобы изменить или удалить пароль для резервного копирования"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Новый пароль для резервной копии установлен"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Пароли не совпадают"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Не удалось установить пароль для резервной копии"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Цвета, оптимизированные для цифрового контента"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Неактивные приложения"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Выключено. Нажмите, чтобы включить."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Включено. Нажмите, чтобы отключить."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Работающие приложения"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Просмотр и управление работающими приложениями"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Ночной режим"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Коррекция цвета"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось около <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Отключено администратором"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Главная"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml
index 6d178a9..6483b18 100644
--- a/packages/SettingsLib/res/values-si-rLK/strings.xml
+++ b/packages/SettingsLib/res/values-si-rLK/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi රෝම් පරිලෝකන වෙතට සැමවිට අවසර දෙන්න"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ලෙගසි DHCP සේවාලාභියා භාවිත කරන්න"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"සෙලියුලර් දත්ත සැමවිට ක්‍රියාකාරීය"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"නිරපේක්ෂ හඩ පරිමාව අබල කරන්න"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"නොරැහැන් සංදර්ශක සහතිකය සඳහා විකල්ප පෙන්වන්න"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ලොග් මට්ටම වැඩි කරන්න, Wi‑Fi තෝරනයෙහි SSID RSSI අනුව පෙන්වන්න"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"සබල විට Wi‑Fi සිග්නලය අඩු විට Wi‑Fi දත්ත සම්බන්ධතාවය සෙලියුලර් වෙත භාර දීමට වඩා ආක්‍රමණික වේ"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"මෙම සැකසීම් වර්ධක භාවිතය සඳහා පමණි. ඔබගේ උපාංගයේ සහ යෙදුම්වල අක්‍රිය වීමට හෝ වැරදි ක්‍රියා කෙරුමකට ඒවා බලපෑ හැක."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ඔස්සේ යෙදුම් සත්‍යාපනය කරගන්න"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT හරහා ස්ථාපනය වූ යෙදුම්, විනාශකාරී ක්‍රියාවන් ඇත්දැයි පරික්ෂාකර බලන්න."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"පිළිගත නොහැකි ලෙස වැඩි හඩ පරිමාව හෝ පාලනය නොමැති වීම යනාදී දුරස්ථ උපාංග සමගින් වන හඬ පරිමා ගැටලුවලදී බ්ලූටූත් නිරපේක්ෂ හඬ පරිමා විශේෂාංගය අබල කරයි."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"අභ්‍යන්තර අන්තය"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"දේශීය ෂෙල් ප්‍රවේශනය පිරිනමන ටර්මිනල් යෙදුම සබල කරන්න"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP පරික්ෂාව"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"මූලික පොටේ යෙදුම්, දිගු මෙහෙයුම් කරන විට තිරය ෆ්ලෑෂ් කරන්න"</string>
     <string name="pointer_location" msgid="6084434787496938001">"සූචක පිහිටීම"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"තිර උඩැතිරිය වර්තමාන ස්පර්ශ දත්ත පෙන්වයි"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"තට්ටු කිරීම් පෙන්වන්න"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"තට්ටු කිරීම් සඳහා දෘශ්‍ය ප්‍රතිපෝෂණ පෙන්වන්න"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"පෘෂ්ඨ යාවත්කාලීන පෙන්වන්න"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"යාවත්කාලින වනවිට මුළු කවුළු තලයම දැල්වෙන්න"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU පෙනුම් යාවත්කාලීන පෙන්වන්න"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරයි."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ඩෙස්ක්ටොප් උපස්ථ මුරපදය"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ දැනට ආරක්ෂා කර නොමැත"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ සඳහා මුරපදය වෙනස් කිරීමට හෝ ඉවත් කිරීමට තට්ටු කරන්න"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"නව උපස්ථ මුරපදය සකසන ලදි"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"නව මුරපදය සහ සත්‍යාපනය නොගැළපුනි"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"උපස්ථ මුරපදය පිහිටුවීම අසාර්ථකය"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"ඩිජිටල් අන්තර්ගතය සඳහා වර්ණ ප්‍රශස්ත කරන ලද"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"අක්‍රිය යෙදුම්"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"අක්‍රියයි. ටොගල කිරීමට තට්ටු කරන්න."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"සක්‍රියයි. ටොගල කිරීමට තට්ටු කරන්න."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"ධාවනය වන සේවා"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"දැනට ධාවනය වන සේවා බලන්න සහ පාලනය කරන්න"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"රාත්‍රී ප්‍රකාරය"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"වර්ණ නිවැරදි කිරීම"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්‍රියාකාරිත්වයට බලපෑ හැක."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආසන්න <xliff:g id="TIME">%2$s</xliff:g> වම"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"පරිපාලක විසින් අබල කරන ලදී"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"මුල් පිටුව"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 658b014..d8e2389 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vždy povoliť funkciu Wi-Fi Roam Scans"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Použiť starý klient DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobilné dáta vždy aktívne"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zakázať absolútnu hlasitosť"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Zobraziť možnosti certifikácie bezdrôtového zobrazenia"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Zvýšiť úroveň denníkov Wi-Fi, zobrazovať podľa SSID RSSI pri výbere siete Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Keď túto možnosť zapnete, Wi-Fi bude agresívnejšie odovzdávať dát. pripoj. na mob. sieť vtedy, keď bude slabý signál Wi-Fi"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Tieto nastavenia sú určené len pre vývojárov. Môžu spôsobiť poruchu alebo nesprávne fungovanie zariadenia a nainštalovaných aplikácií."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Overovať aplikácie z USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrolovať škodlivosť aplikácií nainštalovaných pomocou nástroja ADB alebo ADT"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Umožňuje zakázať funkciu absolútnej hlasitosti rozhrania Bluetooth v prípade problémov s hlasitosťou na vzdialených zariadeniach, ako je napríklad neprijateľne vysoká hlasitosť alebo absencia ovládacích prvkov."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Miestny terminál"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Povoliť terminálovú apl. na miestny prístup k prostrediu shell"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Kontrola HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Úprava farieb"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Zakázané správcom"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Domov"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7b63d5d..fa0e784 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vedno omogoči iskanje omrežij Wi-Fi za gostovanje"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Uporaba starejšega odjemalca DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Prenos podatkov v mobilnih omrežjih je vedno aktiven"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Onemogočanje absolutnega praga glasnosti"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Pokaži možnosti za potrdilo brezžičnega zaslona"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Povečaj raven zapis. dnev. za Wi-Fi; v izbir. Wi‑Fi-ja pokaži glede na SSID RSSI"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Če je ta možnost omogočena, Wi-Fi odločneje preda podatkovno povezavo mobilnemu omrežju, ko je signal Wi-Fi šibek"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Te nastavitve so namenjene samo za razvijanje in lahko povzročijo prekinitev ali napačno delovanje naprave in aplikacij v njej."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Preveri aplikacije prek USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Preveri, ali so aplikacije, nameščene prek ADB/ADT, škodljive."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Onemogoči funkcijo absolutnega praga glasnosti za Bluetooth, če pride do težav z glasnostjo z oddaljenimi napravami, kot je nesprejemljivo visoka glasnost ali pomanjkanje nadzora."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokalni terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Omogočanje terminalske aplikacije za dostop do lokalne lupine"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Preverjanje HDCP"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Popravljanje barv"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Onemogočil skrbnik"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Začetni zaslon"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"Pred toliko časa: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"Še <xliff:g id="ID_1">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml
index f5f3cf2..f9b62fb 100644
--- a/packages/SettingsLib/res/values-sq-rAL/strings.xml
+++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Lejo gjithmonë skanimet për Wi-Fi edhe kur je në lëvizje"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Përdor klientin DHCP të versionit paraprak"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Të dhënat celulare gjithmonë aktive"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Çaktivizo volumin absolut"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Shfaq opsionet për certifikimin e ekranit valor"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Rrit nivelin regjistrues të Wi‑Fi duke shfaqur SSID RSSI-në te Zgjedhësi i Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kur ky funksion aktivizohet, Wi‑Fi bëhet më agresiv në kalimin e lidhjes së të dhënave te rrjeti celular, në rastet kur sinjali Wi‑Fi është i dobët"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Këto cilësime janë të projektuara vetëm për përdorim në programim. Ato mund të shkaktojnë që pajisja dhe aplikacionet në të, të mos punojnë ose të veprojnë në mënyrë të gabuar."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifiko apl. përmes USB-së"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrollo aplikacionet e instaluara nëpërmjet ADB/ADT për sjellje të dëmshme."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Çaktivizon funksionin e volumit absolut të Bluetooth në rast të problemeve të volumit me pajisjet në largësi, si p.sh. një volum i lartë i papranueshëm ose mungesa e kontrollit."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Terminali lokal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktivizo aplikacionin terminal që ofron qasje në guaskën lokale"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Kontrolli HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Ndriço ekranin kur aplikacionet kryejnë operacione të gjata teksa bashkëveprojnë"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Vendndodhja e treguesit"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Mbivendosja e ekranit tregon të dhënat e prekjes"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Shfaq trokitjet"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Shfaq reagimet vizuale për trokitjet"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Shfaq përditësimet e sipërfaqes"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Ndriço të gjitha sipërfaqet e dritares kur ato të përditësohen"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Shfaq përditësimet e pamjes së GPU-së"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Aktivizon mbështetjen për dritaret eksperimentale me formë të lirë."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Fjalëkalimi rezervë i kompjuterit"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Rezervimet e plota në kompjuter nuk janë të mbrojtura aktualisht"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Fjalëkalimi i ri u vendos"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Fjalëkalimi i ri dhe konfirmimi nuk përputhen"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Vendosja e fjalëkalimit dështoi"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Ngjyra të optimizuara për përmbajtjet dixhitale"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Aplikacionet joaktive"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Joaktiv. Trokit për ta ndryshuar."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktiv. Trokit për ta ndryshuar."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Shërbimet në ekzekutim"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Shiko dhe kontrollo shërbimet që po ekzekutohen aktualisht"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Modaliteti i natës"</string>
@@ -299,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Korrigjimi i ngjyrës"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të jetë e plotë"</string>
@@ -314,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Çaktivizuar nga administratori"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"Kreu"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> më parë"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> të mbetura"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index e7b66f4..002e963 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Увек дозволи скенирање Wi‑Fi-ја у ромингу"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Користи застарели DHCP клијент"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Подаци за мобилне уређаје су увек активни"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Онемогући главно подешавање јачине звука"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Приказ опција за сертификацију бежичног екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Повећава ниво евидентирања за Wi‑Fi. Приказ по SSID RSSI-у у бирачу Wi‑Fi мреже"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Када се омогући, Wi‑Fi ће бити агресивнији при пребацивању мреже за пренос података на Мобилну, када је Wi‑Fi сигнал слаб"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ова подешавања су намењена само за програмирање. Могу да изазову престанак функционисања или неочекивано понашање уређаја и апликација на њему."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Верификуј апликације преко USB-а"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Проверава да ли су апликације инсталиране преко ADB-а/ADT-а штетне."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Онемогућава главно подешавање јачине звука на Bluetooth уређају у случају проблема са јачином звука на даљинским уређајима, као што су изузетно велика јачина звука или недостатак контроле."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локални терминал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Омогући аплик. терминала за приступ локалном командном окружењу"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP провера"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Нека екран трепери када апликације обављају дуге операције на главној нити"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Локација показивача"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Постав. елемент са тренутним подацима о додиру"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Приказуј додире"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Приказуј визуелне повратне информације за додире"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Прикажи ажурирања површине"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Осветли све површине прозора када се ажурирају"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Прикажи ажур. GPU приказа"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Лозинка резервне копије за рачунар"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Резервне копије читавог система тренутно нису заштићене"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Постављена је нова лозинка резервне копије"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Нова лозинка и њена потврда се не подударају"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Постављање лозинке резервне копије није успело"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Боје оптимизоване за дигитални садржај"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Неактивне апликације"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Неактивна. Додирните да бисте је активирали."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Активна. Додирните да бисте је деактивирали."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Покренуте услуге"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Приказ и контрола тренутно покренутих услуга"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Ноћни режим"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекција боја"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на перформансе."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостало око <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Онемогућио је администратор"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Почетни"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 35c2e33..9b6f302 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Tillåt alltid sökning efter Wi-Fi-roaming"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Använd äldre DHCP-klient"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobildata alltid aktiverad"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Inaktivera Absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Visa certifieringsalternativ för Wi-Fi-skärmdelning"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Öka loggningsnivån för Wi-Fi, visa per SSID RSSI i Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"När funktionen har aktiverats kommer dataanslutningen lämnas över från Wi-Fi till mobilen på ett aggressivare sätt när Wi-Fi-signalen är svag"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Inställningarna är endast avsedda att användas för utvecklingsändamål. De kan orsaka problem med enheten eller apparna som finns installerade på den."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifiera appar via USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kontrollera om appar som installeras via ADB/ADT kan vara skadliga."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Inaktivera Bluetooth-funktionen Absolute volume om det skulle uppstå problem med volymen på fjärrenheter, t.ex. alldeles för hög volym eller brist på kontroll."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokal terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Aktivera en terminalapp som ger åtkomst till hyllor lokalt"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP-kontroll"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Färgkorrigering"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca <xliff:g id="TIME">%2$s</xliff:g> kvar"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Har inaktiverats av administratören"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Startsida"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index de30b76..f9171ce 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Ruhusu Uchanganuzi wa Matumizi ya Mitandao mingine"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Tumia kiteja cha DHCP kilichopitwa na wakati"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Data ya kifaa cha mkononi inatumika kila wakati"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Zima sauti kamili"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Onyesha chaguo za cheti cha kuonyesha pasiwaya"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Ongeza hatua ya uwekaji kumbukumbu ya Wi-Fi, onyesha kwa kila SSID RSSI kwenye Kichukuzi cha Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Ikiwashwa, Wifi itakabidhi kwa hima muunganisho wa data kwa mtandao wa Simu za Mkononi, mawimbi ya Wifi yanapokuwa hafifu"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Mipangilio hii imekusudiwa kwa matumizi ya usanidi tu. Inaweza kusababisha kifaa chako na programu zilizoko kuvunjika au kutofanya kazi vizuri."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Thibitisha programu kupitia USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kagua programu zilizosakinishwa kupitia ADB/ADT kwa tabia ya kudhuru."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Huzima kipengele cha Bluetooth cha sauti kamili kunapotokea matatizo ya sauti katika vifaa vya mbali kama vile sauti ya juu mno au inaposhindikana kuidhibiti."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Kituo cha karibu"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Washa programu ya mwisho inayotoa ufikiaji mkuu wa karibu"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Inakagua HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Usahihishaji wa rangi"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takriban <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Msimamizi amezima mapendeleo ya mipangilio"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Mwanzo"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml
index af2d9c3..56970a7 100644
--- a/packages/SettingsLib/res/values-ta-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"எப்போதும் வைஃபை ரோமிங் ஸ்கேன்களை அனுமதி"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"அதிகாரப்பூர்வ DHCP க்ளையன்ட்டைப் பயன்படுத்து"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"செல்லுலார் தரவு எப்போதும் இயக்கத்தில்"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கு"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"வயர்லெஸ் காட்சி சான்றுக்கான விருப்பங்களைக் காட்டு"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wifi நுழைவு அளவை அதிகரித்து, வைஃபை தேர்வியில் ஒவ்வொன்றிற்கும் SSID RSSI ஐ காட்டுக"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"இயக்கப்பட்டதும், வைஃபை சிக்னல் குறையும் போது, வைஃபை முழுமையாக ஒத்துழைக்காமல் இருப்பதால் செல்லுலாரின் தரவு இணைப்புக்கு மாறும்"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"இந்த அமைப்பு மேம்பட்டப் பயன்பாட்டிற்காக மட்டுமே. உங்கள் சாதனம் மற்றும் அதில் உள்ள பயன்பாடுகளைச் சிதைக்கும் அல்லது தவறாகச் செயல்படும் வகையில் பாதிப்பை ஏற்படுத்தும்."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB பயன்பாடுகளை சரிபார்"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"தீங்கு விளைவிக்கும் செயல்பாட்டை அறிய ADB/ADT மூலம் நிறுவப்பட்டப் பயன்பாடுகளைச் சரிபார்."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"மிகவும் அதிகமான ஒலியளவு அல்லது கட்டுப்பாடு இழப்பு போன்ற தொலைநிலைச் சாதனங்களில் ஏற்படும் ஒலி தொடர்பான சிக்கல்கள் இருக்கும் சமயங்களில், புளூடூத் அப்சல்யூட் ஒலியளவு அம்சத்தை முடக்கும்."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"அக முனையம்"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"அக ஷெல் அணுகலை வழங்கும் இறுதிப் பயன்பாட்டை இயக்கு"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP சரிபார்ப்பு"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"முக்கிய தொடரிழையில் நீண்ட நேரம் செயல்படும்போது திரையைக் காட்சிப்படுத்து"</string>
     <string name="pointer_location" msgid="6084434787496938001">"குறிப்பான் இடம்"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"திரையின் மேல் அடுக்கானது தற்போது தொடப்பட்டிருக்கும் தரவைக் காண்பிக்கிறது"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"தட்டல்களைக் காட்டு"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"தட்டல்கள் குறித்த காட்சி வடிவக் கருத்தைக் காட்டு"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"மேலோட்ட புதுப்பிப்புகளைக் காட்டு"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"சாளரத்தின் பரப்புநிலைகள் புதுப்பிக்கப்படும்போது, அவற்றை முழுவதுமாகக் காட்டு"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU காட்சி புதுப்பிப்புகளைக் காட்டு"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"பரிசோதனைக்குரிய குறிப்பிட்ட வடிவமில்லாத சாளரங்களுக்கான ஆதரவை இயக்கும்."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"டெஸ்க்டாப் காப்புப்பிரதி கடவுச்சொல்"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"டெஸ்க்டாப்பின் முழு காப்புப்பிரதிகள் தற்போது பாதுகாக்கப்படவில்லை"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"டெஸ்க்டாப்பின் முழுக் காப்புப் பிரதிகளுக்கான கடவுச்சொல்லை மாற்ற அல்லது அகற்ற, தட்டவும்"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"புதிய காப்புப் பிரதியின் கடவுச்சொல் அமைக்கப்பட்டது"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"புதிய கடவுச்சொல்லும், உறுதிப்படுத்தலுக்கான கடவுச்சொல்லும் பொருந்தவில்லை"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"காப்புப் பிரதி கடவுச்சொல்லை அமைப்பதில் தோல்வி"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"டிஜிட்டல் உள்ளடக்கத்திற்கு ஏற்ப மேம்படுத்தப்பட்ட வண்ணங்கள்"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"செயலில் இல்லாத பயன்பாடுகள்"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"செயலில் இல்லை. மாற்ற, தட்டவும்."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"செயலில் உள்ளது. மாற்ற, தட்டவும்."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"இயங்கும் சேவைகள்"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"தற்போது இயக்கத்தில் இருக்கும் சேவைகளைப் பார்த்து கட்டுப்படுத்து"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"இரவு பயன்முறை"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"வண்ணத்திருத்தம்"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"தோராயம்: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> உள்ளது"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"முழு சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"நிர்வாகி முடக்கியுள்ளார்"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"முகப்பு"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml
index e7de5b5..5a8c824 100644
--- a/packages/SettingsLib/res/values-te-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-te-rIN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi‑Fi సంచార స్కాన్‌లను ఎల్లప్పుడూ అనుమతించు"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"లెగసీ DHCP క్లయింట్‌ను ఉపయోగించు"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"ఎల్లప్పుడూ సెల్యులార్ డేటాను సక్రియంగా ఉంచు"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"సంపూర్ణ వాల్యూమ్‌‍ను నిలిపివేయి"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"వైర్‌లెస్ ప్రదర్శన ప్రమాణపత్రం కోసం ఎంపికలను చూపు"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi‑Fi ఎంపికలో SSID RSSI ప్రకారం చూపబడే Wi‑Fi లాగింగ్ స్థాయిని పెంచండి"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"ప్రారంభించబడినప్పుడు, Wi‑Fi సిగ్నల్ బలహీనంగా ఉంటే డేటా కనెక్షన్‌ను సెల్యులార్‌కి మార్చేలా Wi‑Fiపై మరింత తీవ్ర ఒత్తిడి కలుగుతుంది"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"ఈ సెట్టింగ్‌లు అభివృద్ధి వినియోగం కోసం మాత్రమే ఉద్దేశించబడినవి. వీటి వలన మీ పరికరం మరియు దీనిలోని అనువర్తనాలు విచ్ఛిన్నం కావచ్చు లేదా తప్పుగా ప్రవర్తించవచ్చు."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB ద్వారా అనువర్తనాలను ధృవీకరించు"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"హానికరమైన ప్రవర్తన కోసం ADB/ADT ద్వారా ఇన్‌స్టాల్ చేయబడిన అనువర్తనాలను తనిఖీ చేయి."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"రిమోట్ పరికరాల్లో ఆమోదించలేని స్థాయిలో అధిక వాల్యూమ్ ఉండటం లేదా వాల్యూమ్ నియంత్రణ లేకపోవడం వంటి సమస్యలు ఉంటే బ్లూటూత్ సంపూర్ణ వాల్యూమ్ లక్షణాన్ని నిలిపివేస్తుంది."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"స్థానిక టెర్మినల్"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"స్థానిక షెల్ ప్రాప్యతను అందించే టెర్మినల్ అనువర్తనాన్ని ప్రారంభించు"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP తనిఖీ"</string>
@@ -294,6 +296,7 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"రంగు సవరణ"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
+    <string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string>
@@ -309,6 +312,7 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"నిర్వాహకుడు నిలిపివేసారు"</string>
-    <!-- no translation found for home (8263346537524314127) -->
-    <skip />
+    <string name="home" msgid="8263346537524314127">"హోమ్"</string>
+    <string name="charge_length_format" msgid="8978516217024434156">"<xliff:g id="ID_1">%1$s</xliff:g> క్రితం"</string>
+    <string name="remaining_length_format" msgid="7886337596669190587">"<xliff:g id="ID_1">%1$s</xliff:g> మిగిలి ఉంది"</string>
 </resources>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 0e7ab5e..5ef3168 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ใช้การสแกน Wi-Fi ข้ามเครือข่ายเสมอ"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"ใช้ไคลเอ็นต์ DHCP เดิม"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"เปิดใช้ข้อมูลมือถือเสมอ"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ปิดใช้การควบคุมระดับเสียงของอุปกรณ์อื่น"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"แสดงตัวเลือกสำหรับการรับรองการแสดงผล แบบไร้สาย"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"เพิ่มระดับการบันทึก Wi‑Fi แสดงต่อ SSID RSSI ในตัวเลือก Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"เมื่อเปิดใช้แล้ว Wi-Fi จะส่งผ่านการเชื่อมต่อข้อมูลไปยังเครือข่ายมือถือในทันทีที่พบสัญญาณ Wi-Fi อ่อน"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"การตั้งค่านี้มีไว้เพื่อการพัฒนาเท่านั้น จึงอาจทำให้อุปกรณ์และแอปพลิเคชันที่มีอยู่เสียหายหรือทำงานผิดพลาดได้"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"ยืนยันแอปพลิเคชันผ่าน USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ตรวจสอบแอปพลิเคชันที่ติดตั้งผ่าน ADB/ADT เพื่อตรวจดูพฤติกรรมที่เป็นอันตราย"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ปิดใช้คุณลักษณะการควบคุมระดับเสียงของอุปกรณ์อื่นผ่านบลูทูธในกรณีที่มีปัญหาเกี่ยวกับระดับเสียงของอุปกรณ์ระยะไกล เช่น ระดับเสียงที่ดังเกินไปหรือระดับเสียงที่ไม่มีการควบคุม"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"เทอร์มินัลในตัวเครื่อง"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"เปิดใช้งานแอปเทอร์มินัลที่ให้การเข้าถึงเชลล์ในตัวเครื่อง"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"การตรวจสอบ HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"การแก้สี"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็ม"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"ปิดใช้โดยผู้ดูแลระบบ"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"หน้าแรก"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 77da07b..8a7d6aa 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Palaging payagan ang Mga Pag-scan sa Roaming ng Wi‑Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Gumamit ng legacy na DHCP client"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Palaging aktibo ang cellular data"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"I-disable ang absolute volume"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Ipakita ang mga opsyon para sa certification ng wireless display"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Pataasin ang antas ng Wi‑Fi logging, ipakita sa bawat SSID RSSI sa Wi‑Fi Picker"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Kapag naka-enable, mas magiging agresibo ang Wi‑Fi sa paglipat ng koneksyon ng data sa Cellular, kapag mahina ang signal ng Wi‑Fi"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Nilalayon ang mga setting na ito para sa paggamit sa pag-develop lamang. Maaaring magsanhi ang mga ito ng pagkasira o hindi paggana nang maayos ng iyong device at mga application na nandito."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"I-verify ang mga app sa USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Tingnan kung may nakakahamak na pagkilos sa apps na na-install sa pamamagitan ng ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Dini-disable ang absolute volume feature ng Bluetooth kung may mga isyu sa volume ang mga malayong device gaya ng hindi katanggap-tanggap na malakas na volume o kawalan ng kontrol."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Lokal na terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Paganahin ang terminal app na nag-aalok ng lokal na shell access"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Pagsusuring HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Pagtatama ng kulay"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa pagganap."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Na-disable ng administrator"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Home"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 9780953..11b975e 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Kablosuz Dolaşım Taramalarına daima izin ver"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Eski DHCP istemcisini kullan"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Hücresel veri her zaman etkin"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Mutlak sesi iptal et"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Kablosuz ekran sertifikası seçeneklerini göster"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Kablosuz günlük kaydı seviyesini artır. Kablosuz Seçici\'de her bir SSID RSSI için göster."</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Etkinleştirildiğinde, Kablosuz ağ sinyali zayıfken veri bağlantısının Hücresel ağa geçirilmesinde daha agresif olunur"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Bu ayarlar yalnızca geliştirme amaçlıdır. Cihazınızın veya cihazdaki uygulamaların bozulmasına veya hatalı çalışmasına neden olabilir."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB\'den yüklenen uygulamaları doğrula"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT üzerinden yüklenen uygulamaları zararlı davranışlara karşı denetle."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Uzak cihazda sesin aşırı yüksek olması veya kontrol edilememesi gibi ses sorunları olması ihtimaline karşı Bluetooh mutlak ses özelliğini iptal eder."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Yerel terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Yerel kabuk erişimi sunan terminal uygulamasını etkinleştir"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP denetimi"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Uyg. ana işlem parçasında uzun işlem yap. ekr. yakıp söndür"</string>
     <string name="pointer_location" msgid="6084434787496938001">"İşaretçi konumu"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Mevcut dokunmatik verilerini gösteren yer paylaşımı"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Hafifçe dokunmayı göster"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Hafifçe dokunmalarda görsel geri bildirim göster"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Yüzey güncellemelerini göster"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Güncelleme sırasında tüm pencere yüzeylerini çiz"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"GPU görünüm güncellemelerini göster"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Deneysel serbest biçimli pencereleri etkinleştirir."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Masaüstü yedekleme şifresi"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Masaüstü tam yedeklemeleri şu an korunmuyor"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Masaüstü tam yedeklemelerinin şifresini değiştirmek veya kaldırmak için hafifçe dokunun"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Yeni yedekleme şifresi ayarlandı"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Yeni şifre ve onayı eşleşmiyor."</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Yedekleme şifresi ayarlanamadı"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Dijital içerik için optimize edilmiş renkler"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Devre dışı uygulamalar"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Etkin değil. Geçiş yapmak için hafifçe dokunun."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Etkin. Geçiş yapmak için hafifçe dokunun."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Çalışan hizmetler"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Şu anda çalışan hizmetleri görüntüle ve denetle"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Gece modu"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Renk düzeltme"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Yönetici tarafından devre dışı bırakıldı"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Ana Ekran"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 15419bd..ad18d7f 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Завжди шукати мережі Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Використовувати старий клієнт DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Не вимикати передавання даних"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Вимкнути абсолютну гучність"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Показати параметри сертифікації бездротового екрана"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Показувати в журналі RSSI для кожного SSID під час вибору Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Примусово перемикатися на мобільну мережу, коли сигнал Wi-Fi слабкий"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Ці налаштування застосовуються лише з метою розробки. Вони можуть спричиняти вихід з ладу або неправильне функціонування вашого пристрою чи програм у ньому."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Встановлення через USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Перевіряти безпеку додатків, установлених через ADB/ADT."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Функція абсолютної гучності Bluetooth вимикається, якщо на віддалених пристроях виникають проблеми, як-от надто висока гучність або втрата контролю."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Локальний термінал"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Увімк. програму-термінал, що надає локальний доступ до оболонки"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Перевірка HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Корекція кольору"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилось близько <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Вимкнено адміністратором"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Головний екран"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml
index e2eac3f..670f2e6 100644
--- a/packages/SettingsLib/res/values-ur-rPK/strings.xml
+++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"‏ہمیشہ Wi‑Fi روم اسکینز کی اجازت دیں"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"‏پرانا DHCP کلائنٹ استعمال کریں"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"سیلولر ڈیٹا کو ہمیشہ فعال رکھیں"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"مطلق والیوم کو غیر فعال کریں"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"وائرلیس ڈسپلے سرٹیفیکیشن کیلئے اختیارات دکھائیں"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"‏Wi‑Fi لاگنگ لیول میں اضافہ کریں، Wi‑Fi منتخب کنندہ میں فی SSID RSSI دکھائیں"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"‏فعال ہونے پر، جب Wi‑Fi سگنل کمزور ہوگا تو Wi‑Fi سیلولر پر ڈیٹا کنکشن بھیجنے کیلئے مزید جارحانہ کاروائی کرے گا۔"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"یہ ترتیبات صرف ڈویلپمنٹ استعمال کے ارادے سے ہیں۔ ان سے آپ کا آلہ اور اس پر موجود ایپلیکیشنز بریک ہو سکتی یا غلط برتاؤ کر سکتی ہیں۔"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"‏USB پر ایپس کی توثیق کریں"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"‏نقصان دہ رویے کے مدنظر ADB/ADT کی معرفت انسٹال شدہ ایپس کی جانچ کریں۔"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"ریموٹ آلات کے ساتھ والیوم کے مسائل مثلاً نا قابل قبول حد تک بلند والیوم یا کنٹرول نہ ہونے کی صورت میں بلو ٹوتھ مطلق والیوم والی خصوصیت کو غیر فعال کریں۔"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"مقامی ٹرمینل"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"مقامی شیل رسائی پیش کرنے والی ٹرمینل ایپ فعال کریں"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"‏HDCP چیکنگ"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"ایپس کے اصل تھریڈ پر طویل اعمال انجام دیتے وقت اسکرین کو فلیش کریں"</string>
     <string name="pointer_location" msgid="6084434787496938001">"پوائنٹر مقام"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"موجودہ ٹچ ڈیٹا دکھانے والا اسکرین اوور لے"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"تھپتھپاہٹیں دکھائیں"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"تھپتھپاہٹوں کیلئے بصری تاثرات دکھائیں"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"سطح کے اپ ڈیٹس دکھائیں"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"اپ ڈیٹ ہونے پر ونڈو کی پوری سطحیں جھلملائیں"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"‏GPU منظر اپ ڈیٹس دکھائیں"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"‏تجرباتی freeform ونڈوز کے لئے سپورٹ فعال کرتا ہے۔"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"ڈیسک ٹاپ کا بیک اپ پاس ورڈ"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"ڈیسک ٹاپ کے مکمل بیک اپس فی الحال محفوظ کیے ہوئے نہیں ہیں"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"ڈیسک ٹاپ کے مکمل بیک اپس کیلئے پاس ورڈ کو تبدیل کرنے یا ہٹانے کیلئے تھپتھپائیں"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"بیک اپ کا نیا پاس ورڈ سیٹ کر دیا گیا"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"نیا پاس ورڈ اور تصدیق مماثل نہیں ہے"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"بیک اپ پاس ورڈ ترتیب دینے میں ناکامی"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"ڈیجیٹیل مواد کیلئے بہترین کردہ رنگ"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"غیر فعال ایپس"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"غیر فعال۔ ٹوگل کرنے کیلئے تھپتھپائیں۔"</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"فعال۔ ٹوگل کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"چل رہی سروسز"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"فی الحال چل رہی سروسز دیکھیں اور انہیں کنٹرول کریں"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"رات موڈ"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"رنگ کی اصلاح"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g>‎ - تقریبا <xliff:g id="TIME">%2$s</xliff:g> باقی"</string>
     <string name="power_charging" msgid="1779532561355864267">"‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>‎"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"‏‎<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>‎ پورا ہونے تک"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"منتظم نے غیر فعال کر دیا"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"ہوم"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 12d0e8c..e7dccae 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi tarmoqlarini qidirishga doim ruxsat"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Eski DHCP mijoz-dasturidan foydalanish"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Mobil internet o‘chirilmasin"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Ovoz balangligining mutlaq darajasini o‘chirib qo‘yish"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Simsiz monitorlarni sertifikatlash parametrini ko‘rsatish"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Wi-Fi ulanishini tanlashda har bir SSID uchun jurnalda ko‘rsatilsin"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Agar ushbu funksiya yoqilsa, Wi-Fi signali past bo‘lganda internetga ulanish majburiy ravishda mobil internetga o‘tkaziladi."</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Bu sozlamalar faqat dasturlash maqsadlariga mo‘ljallangan. Shuning uchun, ular qurilmangizga va undagi ilovalariga shikast yetkazib, noto‘g‘ri ishlashiga sabab bo‘lishi mumkin."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"USB orqali o‘rnatish"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"ADB/ADT orqali o‘rnatilgan ilovalar xavfsizligini tekshiring"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Masofadan ulanadigan qurilmalar bilan muammolar yuz berganda, jumladan, juda baland ovoz yoki sozlamalarni boshqarib bo‘lmaydigan holatlarda Bluetooth ovozi balandligining mutlaq darajasini o‘chirib qo‘yadi."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Mahalliy terminal"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Mahalliy terminalga kirishga ruxsat beruvchi terminal ilovani faollashtirish"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP tekshiruvi"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Uzun amallar vaqtida ekranni miltillatish"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Kursor joylashuvi"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Ekranda bosilgan va tegilgan joylarni vizuallashtirish"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Bosishlarni ko‘rsatish"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Ekranda bosilgan joylardagi nuqtalarni ko‘rsatish"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Yuza yangilanishlarini ko‘rsatish"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Yangilangandan so‘ng to‘liq oyna sirtlarini miltillatish"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Ekran yangilanishlarini ko‘rsatish"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Tajribaviy erkin shakldagi oynalar ta’minotini yoqadi"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Zaxira nusxa uchun parol"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Kompyuterdagi zaxira nusxalar hozirgi vaqtda himoyalanmagan"</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ish stoli to‘liq zaxira nusxalari parolini o‘zgartirish yoki o‘chirish uchun bu yerni bosing"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Yangi zaxira paroli o‘rnatildi"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Parollar bir-biriga mos kelmadi"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Zaxira parolini o‘rnatib bo‘lmadi"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Raqamli kontentga moslashtirilgan ranglar"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Nofaol ilovalar"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Nofaol. O‘zgartirish uchun bu yerga bosing."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Faol. O‘zgartirish uchun bu yerga bosing."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Ishlab turgan ilovalar"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Ishlab turgan ilovalarni ko‘rish va boshqarish"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Tungi rejim"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Rangni tuzatish"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, to‘lguncha"</string>
@@ -310,10 +309,13 @@
     <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Quvvat olmoqda (AC)"</string>
     <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Quvvat olmoqda (USB)"</string>
     <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Simsiz quvvat olmoqda"</string>
-    <string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvatlantirilmayapti"</string>
+    <string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvat olmayapti"</string>
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Administrator tomonidan o‘chirib qo‘yilgan"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Bosh ekran"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index a149969..c803415 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Luôn cho phép quét chuyển vùng Wi‑Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Sử dụng ứng dụng DHCP cũ"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Dữ liệu di động luôn hoạt động"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Vô hiệu hóa âm lượng tuyệt đối"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Hiển thị tùy chọn chứng nhận hiển thị không dây"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"Tăng mức ghi nhật ký Wi‑Fi, hiển thị mỗi SSID RSSI trong bộ chọn Wi‑Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Khi được bật, Wi‑Fi sẽ tích cực hơn trong việc chuyển vùng kết nối dữ liệu sang mạng di động khi tín hiệu Wi‑Fi yếu"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Những cài đặt này chỉ dành cho mục đích phát triển. Chúng có thể làm cho thiết bị và ứng dụng trên thiết bị của bạn bị lỗi và hoạt động sai."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Xác minh ứng dụng qua USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Kiểm tra các ứng dụng được cài đặt qua ADB/ADT để xem có hoạt động gây hại hay không."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Vô hiệu hóa tính năng âm lượng tuyệt đối qua Bluetooth trong trường hợp xảy ra sự cố về âm lượng với các thiết bị từ xa, chẳng hạn như âm lượng lớn không thể chấp nhận được hoặc thiếu kiểm soát."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Dòng lệnh cục bộ"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Bật ứng dụng dòng lệnh cung cấp quyền truy cập vỏ cục bộ"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Kiểm tra HDCP"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Sửa màu"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Bị tắt bởi quản trị viên"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Màn hình chính"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 27e8972..54a6e7c 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允许WLAN漫游扫描"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"使用旧版 DHCP 客户端"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"始终开启移动数据网络"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用绝对音量功能"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"显示无线显示认证选项"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"提升WLAN日志记录级别(在WLAN选择器中显示每个SSID的RSSI)"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"开启此设置后,系统会在WLAN信号较弱时,主动将网络模式从WLAN网络切换到移动数据网络"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"这些设置仅适用于开发工作。一旦启用,会导致您的设备以及设备上的应用崩溃或出现异常。"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"通过USB验证应用"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"通过 ADB/ADT 检查安装的应用是否存在有害行为。"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"停用蓝牙绝对音量功能,即可避免在连接到远程设备时出现音量问题(例如音量高得让人无法接受或无法控制音量等)。"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"本地终端"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"启用终端应用,以便在本地访问 Shell"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP 检查"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"此功能为实验性功能,可能会影响性能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用大约<xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"已被管理员禁用"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"主屏幕"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index af1223c..e95a324 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"永遠允許 Wi-Fi 漫遊掃瞄"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"使用舊的 DHCP 用戶端"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"經常啟用流動數據"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"啟用時,Wi-Fi 連線會在訊號不穩的情況下更積極轉換成流動數據連線"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"這些設定僅供開發用途,可能會導致您的裝置及應用程式損毀或運作不正常。"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"透過 USB 驗證應用程式"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"透過 ADB/ADT 檢查安裝的應用程式有否有害的行為。"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"連線至遠端裝置時,如發生音量過大或無法控制音量等問題,請停用藍牙絕對音量功能。"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"本機終端機"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP 檢查"</string>
@@ -206,8 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"當應用程式在主執行緒中進行長時間作業時,讓螢幕閃爍"</string>
     <string name="pointer_location" msgid="6084434787496938001">"指標位置"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"在螢幕上重疊顯示目前的觸控資料"</string>
-    <string name="show_touches" msgid="2642976305235070316">"顯示觸控回應"</string>
-    <string name="show_touches_summary" msgid="6101183132903926324">"顯示觸控位置的視覺回應"</string>
+    <string name="show_touches" msgid="2642976305235070316">"顯示輕按回應"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"顯示輕按位置的視覺回應"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"顯示表層更新"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"更新表層時閃動整個視窗表層"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"顯示 GPU 畫面更新"</string>
@@ -251,7 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"啟用實驗版自由形態視窗的支援功能。"</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"桌面電腦備份密碼"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"桌上電腦的完整備份目前未受保護"</string>
-    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"輕按即可變更或移除電腦完整備份的密碼"</string>
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"輕按即可變更或移除桌上電腦完整備份的密碼"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"已設定新備份密碼"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"新密碼與確認密碼不符"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"無法設定備份密碼"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘大約 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"管理員已停用此設定"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"主畫面"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index f268ff9..bf7ea4e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"一律允許 Wi-Fi 漫遊掃描"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"使用舊版 DHCP 用戶端"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"行動數據連線一律保持啟用狀態"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"停用絕對音量功能"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"顯示無線螢幕分享認證的選項"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"讓 Wi‑Fi 記錄功能升級,在 Wi‑Fi 選擇器中依每個 SSID RSSI 顯示 Wi‑Fi 詳細紀錄"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"啟用時,Wi-Fi 連線在訊號不穩的情況下會更積極轉換成行動數據連線"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"這些設定僅供開發之用,可能導致您的裝置及裝置中的應用程式毀損或運作異常。"</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"透過 USB 驗證應用程式"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"透過 ADB/ADT 檢查安裝的應用程式是否出現有害的行為。"</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"只要停用藍牙絕對音量功能,即可避免在連線到遠端裝置時,發生音量過大或無法控制音量等問題。"</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"本機終端機"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"啟用可提供本機命令介面存取權的終端機應用程式"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"HDCP 檢查"</string>
@@ -294,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"色彩校正"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大約還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string>
@@ -309,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"已由管理員停用"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"主畫面"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index f372057..c450f77 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -165,6 +165,7 @@
     <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Vumela njalo ukuskena kokuzula kwe-Wi-Fi"</string>
     <string name="legacy_dhcp_client" msgid="694426978909127287">"Sebenzisa iklayenti le-legacy le-DHCP"</string>
     <string name="mobile_data_always_on" msgid="7745605759775320362">"Idatha yeselula ihlala isebenza"</string>
+    <string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"Khubaza ivolumu ngokuphelele"</string>
     <string name="wifi_display_certification_summary" msgid="1155182309166746973">"Bonisa izinketho zokunikeza isitifiketi ukubukeka okungenantambo"</string>
     <string name="wifi_verbose_logging_summary" msgid="6615071616111731958">"khuphula izinga lokungena le-Wi-Fi, bonisa nge-SSID RSSI engayodwana kusikhethi se-Wi-Fi"</string>
     <string name="wifi_aggressive_handover_summary" msgid="6328455667642570371">"Uma inikwe amandla, i-Wi-Fi izoba namandla kakhulu ekunikezeleni ukuxhumeka kwedatha kuselula, uma isiginali ye-Wi-Fi iphansi"</string>
@@ -185,6 +186,7 @@
     <string name="dev_settings_warning_message" msgid="2298337781139097964">"Lezi zilungiselelo zenzelwe ukusetshenziswa ukuthuthukisa kuphela. Zingadala ukuthi idivayisi yakho kanye nensiza ekuyona ukuthi iphuke noma iziphathe kabi."</string>
     <string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Qiniseka izinhlelo zokusebenza nge-USB"</string>
     <string name="verify_apps_over_usb_summary" msgid="9164096969924529200">"Hlola izinhlelo zokusebenza ezifakiwe nge-ADB/ADT ngokuziphatha okuyingozi."</string>
+    <string name="bluetooth_disable_absolute_volume_summary" msgid="6031284410786545957">"Ikhubaza isici esiphelele sevolumu ye-Bluetooth uma kuba nezinkinga zevolumu ngamadivayisi esilawuli kude ezifana nevolumu ephezulu noma eshoda ngokulawuleka."</string>
     <string name="enable_terminal_title" msgid="95572094356054120">"Itheminali yasendaweni"</string>
     <string name="enable_terminal_summary" msgid="67667852659359206">"Nika amandla uhlelo lokusebenza letheminali olunikeza ukufinyelela kwasendaweni kwe-shell"</string>
     <string name="hdcp_checking_title" msgid="8605478913544273282">"Ihlola i-HDCP"</string>
@@ -206,10 +208,8 @@
     <string name="strict_mode_summary" msgid="142834318897332338">"Ukuphazimisa isikrini uma izinhlelo zokusebenza ziyenza umsebenzi ngesikhathi eside kuchungechunge olukhulu"</string>
     <string name="pointer_location" msgid="6084434787496938001">"Isikhombi sendawo"</string>
     <string name="pointer_location_summary" msgid="840819275172753713">"Imbondela yesikrini ibonisa idatha yokuthinta yamanje"</string>
-    <!-- no translation found for show_touches (2642976305235070316) -->
-    <skip />
-    <!-- no translation found for show_touches_summary (6101183132903926324) -->
-    <skip />
+    <string name="show_touches" msgid="2642976305235070316">"Bonisa amathebhu"</string>
+    <string name="show_touches_summary" msgid="6101183132903926324">"Bonisa izmpendulo ebukekayo ngamathebhu"</string>
     <string name="show_screen_updates" msgid="5470814345876056420">"Buka izibuyekezo ezibonakalayo"</string>
     <string name="show_screen_updates_summary" msgid="2569622766672785529">"Khanyisa ukubonakala kwalo lonke iwindi uma libuyekezwa"</string>
     <string name="show_hw_screen_updates" msgid="5036904558145941590">"Buka izibuyekezo ze-GPU"</string>
@@ -253,8 +253,7 @@
     <string name="enable_freeform_support_summary" msgid="2252563497485436534">"Inika amandla usekelo lwamawindi okuhlola e-freeform."</string>
     <string name="local_backup_password_title" msgid="3860471654439418822">"Iphasiwedi yokusekela ngokulondoloza ye-Desktop"</string>
     <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Ukusekela ngokulondoloza okugcwele kwe-Desktop akuvikelekile okwamanje."</string>
-    <!-- no translation found for local_backup_password_summary_change (5376206246809190364) -->
-    <skip />
+    <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Thepha ukushintsha noma ukususa iphasiwedi yokwenziwa kwezipele ngokugcwele kwideskithophu"</string>
     <string name="local_backup_password_toast_success" msgid="582016086228434290">"Iphasiwedi entsha eyisipele isethiwe"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Iphasiwedi entsha nokuqinisekisa akufani"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Ukungaphumeleli kokusetha iphasiwedi eyisipele"</string>
@@ -269,10 +268,8 @@
     <item msgid="5363960654009010371">"Imibala elungiselelwe yokuqukethwe kwedijithali"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="1317817863508274533">"Izinhlelo zokusebenza ezingasebenzi"</string>
-    <!-- no translation found for inactive_app_inactive_summary (5091363706699855725) -->
-    <skip />
-    <!-- no translation found for inactive_app_active_summary (4174921824958516106) -->
-    <skip />
+    <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Akusebenzi. Thepha ukuze ushintshe."</string>
+    <string name="inactive_app_active_summary" msgid="4174921824958516106">"Kuyasebenza. Thepha ukuze ushintshe."</string>
     <string name="runningservices_settings_title" msgid="8097287939865165213">"Amasevisi asebenzayo"</string>
     <string name="runningservices_settings_summary" msgid="854608995821032748">"Buka futhi ulawule amasevisi  asebenzayo okwamanje"</string>
     <string name="night_mode_title" msgid="2594133148531256513">"Imodi yasebusuku"</string>
@@ -299,6 +296,8 @@
     <string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Ukulungiswa kombala"</string>
     <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string>
     <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
+    <!-- no translation found for power_remaining_duration_only (4400068916452346544) -->
+    <skip />
     <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - isilinganiso esingu-<xliff:g id="TIME">%2$s</xliff:g> esisele"</string>
     <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
     <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale"</string>
@@ -314,6 +313,9 @@
     <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string>
     <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string>
     <string name="disabled_by_admin_summary_text" msgid="7787027069207263048">"Ikhutshazwe umlawuli"</string>
-    <!-- no translation found for home (8263346537524314127) -->
+    <string name="home" msgid="8263346537524314127">"Ekhaya"</string>
+    <!-- no translation found for charge_length_format (8978516217024434156) -->
+    <skip />
+    <!-- no translation found for remaining_length_format (7886337596669190587) -->
     <skip />
 </resources>
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index 3e1fc4a..4484613 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -24,4 +24,12 @@
     </declare-styleable>
     <attr name="wifi_signal" format="reference" />
 
+    <declare-styleable name="UsageView">
+        <attr name="android:colorAccent" />
+        <attr name="sideLabels" format="reference" />
+        <attr name="bottomLabels" format="reference" />
+        <attr name="textColor" format="color" />
+        <attr name="android:gravity" />
+    </declare-styleable>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index c090468..796273d 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -16,4 +16,6 @@
 
 <resources>
     <color name="disabled_text_color">#66000000</color> <!-- 38% black -->
+
+    <color name="usage_graph_dots">#455A64</color>
 </resources>
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 811751c..9f78e87 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -38,4 +38,18 @@
 
     <dimen name="wifi_preference_badge_padding">8dip</dimen>
 
+    <!-- Usage graph dimens -->
+    <dimen name="usage_graph_area_height">122dp</dimen>
+    <dimen name="usage_graph_margin_top_bottom">9dp</dimen>
+    <dimen name="usage_graph_labels_width">56dp</dimen>
+    <dimen name="usage_graph_labels_padding">16dp</dimen>
+
+    <dimen name="usage_graph_divider_size">1dp</dimen>
+
+    <dimen name="usage_graph_line_width">3dp</dimen>
+    <dimen name="usage_graph_line_corner_radius">6dp</dimen>
+
+    <dimen name="usage_graph_dot_size">.75dp</dimen>
+    <dimen name="usage_graph_dot_interval">7dp</dimen>
+
 </resources>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 32699eb..7012eb2 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -416,6 +416,8 @@
     <string name="legacy_dhcp_client">Use legacy DHCP client</string>
     <!-- Setting Checkbox title whether to always keep cellular data active. [CHAR LIMIT=80] -->
     <string name="mobile_data_always_on">Cellular data always active</string>
+    <!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
+    <string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
 
     <!-- setting Checkbox summary whether to show options for wireless display certification  -->
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
@@ -456,6 +458,8 @@
     <string name="verify_apps_over_usb_title">Verify apps over USB</string>
     <!-- Summary of checkbox setting to perform package verification on apps installed over USB/ADT/ADB [CHAR LIMIT=NONE] -->
     <string name="verify_apps_over_usb_summary">Check apps installed via ADB/ADT for harmful behavior.</string>
+    <!-- Summary of checkbox for disabling Bluetooth absolute volume -->
+    <string name="bluetooth_disable_absolute_volume_summary">Disables the Bluetooth absolute volume feature in case of volume issues with remote devices such as unacceptably loud volume or lack of control.</string>
 
     <!-- Title of checkbox setting that enables the terminal app. [CHAR LIMIT=32] -->
     <string name="enable_terminal_title">Local terminal</string>
@@ -622,12 +626,12 @@
     <!-- UI debug setting: force all activites to be resizable for multiwindow [CHAR LIMIT=50] -->
     <string name="force_resizable_activities">Force activities to be resizable</string>
     <!-- UI debug setting: force allow on external summary [CHAR LIMIT=150] -->
-    <string name="force_resizable_activities_summary">Makes all activities resizable for multi-window, regardless of manifest values.</string>
+    <string name="force_resizable_activities_summary">Make all activities resizable for multi-window, regardless of manifest values.</string>
 
     <!-- UI debug setting: enable freeform window support [CHAR LIMIT=50] -->
     <string name="enable_freeform_support">Enable freeform windows</string>
     <!-- UI debug setting: enable freeform window support summary [CHAR LIMIT=150] -->
-    <string name="enable_freeform_support_summary">Enables support for experimental freeform windows.</string>
+    <string name="enable_freeform_support_summary">Enable support for experimental freeform windows.</string>
 
     <!-- Local (desktop) backup password menu title [CHAR LIMIT=25] -->
     <string name="local_backup_password_title">Desktop backup password</string>
@@ -728,6 +732,9 @@
     <!-- Summary shown for color space correction preference when its value is overridden by another preference [CHAR LIMIT=35] -->
     <string name="daltonizer_type_overridden">Overridden by <xliff:g id="title" example="Simulate color space">%1$s</xliff:g></string>
 
+    <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging/discharging -->
+    <string name="power_remaining_duration_only">Approx. <xliff:g id="time">%1$s</xliff:g> left</string>
+
     <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration -->
     <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g>
         - approx. <xliff:g id="time">%2$s</xliff:g> left</string>
@@ -771,4 +778,16 @@
     <!-- Option in navigation drawer that leads to Settings main screen [CHAR LIMIT=30] -->
     <string name="home">Home</string>
 
+    <string-array name="battery_labels" translatable="false">
+        <item>0%</item>
+        <item>50%</item>
+        <item>100%</item>
+    </string-array>
+
+    <!-- Label for length of time since the battery graph started [CHAR LIMIT=20] -->
+    <string name="charge_length_format"><xliff:g name="time" example="3 hours">%1$s</xliff:g> ago</string>
+
+    <!-- Label for length of time until battery is charged [CHAR LIMIT=20] -->
+    <string name="remaining_length_format"><xliff:g name="time" example="3 hours">%1$s</xliff:g> left</string>
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
index d81bdeb..b16b8ec 100644
--- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
@@ -17,13 +17,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources;
 import android.os.AsyncTask;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
+import android.os.BatteryStats.HistoryItem;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.text.format.Formatter;
+import android.util.SparseIntArray;
 import com.android.internal.os.BatteryStatsHelper;
+import com.android.settingslib.graph.UsageView;
 
 public class BatteryInfo {
 
@@ -31,11 +35,127 @@
     public int mBatteryLevel;
     public boolean mDischarging = true;
     public long remainingTimeUs = 0;
+    public String batteryPercentString;
+    public String remainingLabel;
+    private BatteryStats mStats;
+    private boolean mCharging;
 
     public interface Callback {
         void onBatteryInfoLoaded(BatteryInfo info);
     }
 
+    public void bindHistory(UsageView view) {
+        long startWalltime = 0;
+        long endDateWalltime = 0;
+        long endWalltime = 0;
+        long historyStart = 0;
+        long historyEnd = 0;
+        byte lastLevel = -1;
+        long curWalltime = startWalltime;
+        long lastWallTime = 0;
+        long lastRealtime = 0;
+        int lastInteresting = 0;
+        int pos = 0;
+        boolean first = true;
+        if (mStats.startIteratingHistoryLocked()) {
+            final HistoryItem rec = new HistoryItem();
+            while (mStats.getNextHistoryLocked(rec)) {
+                pos++;
+                if (first) {
+                    first = false;
+                    historyStart = rec.time;
+                }
+                if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
+                        || rec.cmd == HistoryItem.CMD_RESET) {
+                    // If there is a ridiculously large jump in time, then we won't be
+                    // able to create a good chart with that data, so just ignore the
+                    // times we got before and pretend like our data extends back from
+                    // the time we have now.
+                    // Also, if we are getting a time change and we are less than 5 minutes
+                    // since the start of the history real time, then also use this new
+                    // time to compute the base time, since whatever time we had before is
+                    // pretty much just noise.
+                    if (rec.currentTime > (lastWallTime+(180*24*60*60*1000L))
+                            || rec.time < (historyStart+(5*60*1000L))) {
+                        startWalltime = 0;
+                    }
+                    lastWallTime = rec.currentTime;
+                    lastRealtime = rec.time;
+                    if (startWalltime == 0) {
+                        startWalltime = lastWallTime - (lastRealtime-historyStart);
+                    }
+                }
+                if (rec.isDeltaData()) {
+                    if (rec.batteryLevel != lastLevel || pos == 1) {
+                        lastLevel = rec.batteryLevel;
+                    }
+                    lastInteresting = pos;
+                    historyEnd = rec.time;
+                }
+            }
+        }
+        mStats.finishIteratingHistoryLocked();
+        endDateWalltime = lastWallTime + historyEnd - lastRealtime;
+        endWalltime = endDateWalltime + (remainingTimeUs / 1000);
+
+        int i = 0;
+        final int N = lastInteresting;
+        SparseIntArray points = new SparseIntArray();
+        view.clearPaths();
+        view.configureGraph((int) (endWalltime - startWalltime), 100, remainingTimeUs != 0,
+                mCharging);
+        if (endDateWalltime > startWalltime && mStats.startIteratingHistoryLocked()) {
+            final HistoryItem rec = new HistoryItem();
+            while (mStats.getNextHistoryLocked(rec) && i < N) {
+                if (rec.isDeltaData()) {
+                    curWalltime += rec.time - lastRealtime;
+                    lastRealtime = rec.time;
+                    long x = (curWalltime - startWalltime);
+                    if (x < 0) {
+                        x = 0;
+                    }
+                    points.put((int) x, rec.batteryLevel);
+                } else {
+                    long lastWalltime = curWalltime;
+                    if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
+                            || rec.cmd == HistoryItem.CMD_RESET) {
+                        if (rec.currentTime >= startWalltime) {
+                            curWalltime = rec.currentTime;
+                        } else {
+                            curWalltime = startWalltime + (rec.time - historyStart);
+                        }
+                        lastRealtime = rec.time;
+                    }
+
+                    if (rec.cmd != HistoryItem.CMD_OVERFLOW
+                            && (rec.cmd != HistoryItem.CMD_CURRENT_TIME
+                                    || Math.abs(lastWalltime-curWalltime) > (60*60*1000))) {
+                        if (points.size() > 1) {
+                            view.addPath(points);
+                        }
+                        points.clear();
+                    }
+                }
+                i++;
+            }
+        }
+        if (points.size() > 1) {
+            view.addPath(points);
+        }
+        long timePast = endDateWalltime - startWalltime;
+        final Context context = view.getContext();
+        String timeString = context.getString(R.string.charge_length_format,
+                Formatter.formatShortElapsedTime(context, timePast));
+        String remaining = "";
+        if (remainingTimeUs != 0) {
+            remaining = context.getString(R.string.remaining_length_format,
+                    Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000));
+        }
+        view.setBottomLabels(new CharSequence[] { timeString, remaining});
+
+        mStats.finishIteratingHistoryLocked();
+    }
+
     public static void getBatteryInfo(final Context context, final Callback callback) {
         new AsyncTask<Void, Void, BatteryStats>() {
             @Override
@@ -60,23 +180,29 @@
     public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
             BatteryStats stats, long elapsedRealtimeUs) {
         BatteryInfo info = new BatteryInfo();
+        info.mStats = stats;
         info.mBatteryLevel = Utils.getBatteryLevel(batteryBroadcast);
-        String batteryPercentString = Utils.formatPercentage(info.mBatteryLevel);
-        if (batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) == 0) {
+        info.batteryPercentString = Utils.formatPercentage(info.mBatteryLevel);
+        info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+        final Resources resources = context.getResources();
+        if (!info.mCharging) {
             final long drainTime = stats.computeBatteryTimeRemaining(elapsedRealtimeUs);
             if (drainTime > 0) {
                 info.remainingTimeUs = drainTime;
                 String timeString = Formatter.formatShortElapsedTime(context,
                         drainTime / 1000);
-                info.mChargeLabelString = context.getResources().getString(
-                        R.string.power_discharging_duration, batteryPercentString, timeString);
+                info.remainingLabel = resources.getString(R.string.power_remaining_duration_only,
+                        timeString);
+                info.mChargeLabelString = resources.getString(R.string.power_discharging_duration,
+                        info.batteryPercentString, timeString);
             } else {
-                info.mChargeLabelString = batteryPercentString;
+                info.remainingLabel = null;
+                info.mChargeLabelString = info.batteryPercentString;
             }
         } else {
             final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
             final String statusLabel = Utils.getBatteryStatus(
-                    context.getResources(), batteryBroadcast);
+                    resources, batteryBroadcast);
             final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
                     BatteryManager.BATTERY_STATUS_UNKNOWN);
             if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
@@ -95,11 +221,14 @@
                 } else {
                     resId = R.string.power_charging_duration;
                 }
-                info.mChargeLabelString = context.getResources().getString(
-                        resId, batteryPercentString, timeString);
+                info.remainingLabel = resources.getString(R.string.power_remaining_duration_only,
+                        timeString);
+                info.mChargeLabelString = resources.getString(
+                        resId, info.batteryPercentString, timeString);
             } else {
-                info.mChargeLabelString = context.getResources().getString(
-                        R.string.power_charging, batteryPercentString, statusLabel);
+                info.remainingLabel = statusLabel;
+                info.mChargeLabelString = resources.getString(
+                        R.string.power_charging, info.batteryPercentString, statusLabel);
             }
         }
         return info;
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index f885110..c44b638 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -21,10 +21,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.UserInfo;
-import android.graphics.Color;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -227,8 +225,7 @@
             int userId) {
         IPackageManager ipm = AppGlobals.getPackageManager();
         try {
-            ApplicationInfo ai = ipm.getApplicationInfo(packageName, 0, userId);
-            if (ai != null && ((ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0)) {
+            if (ipm.isPackageSuspendedForUser(packageName, userId)) {
                 return getProfileOrDeviceOwner(context, userId);
             }
         } catch (RemoteException e) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java
index 73171c7..1d6197a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java
@@ -65,7 +65,7 @@
     }
 
     public Tile getTile(int position) {
-        return mItems.get(position).tile;
+        return mItems.get(position) != null ? mItems.get(position).tile : null;
     }
 
     @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
new file mode 100644
index 0000000..530ec16
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settingslib.graph;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.CornerPathEffect;
+import android.graphics.DashPathEffect;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Paint.Cap;
+import android.graphics.Paint.Join;
+import android.graphics.Paint.Style;
+import android.graphics.Path;
+import android.graphics.Shader.TileMode;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.SparseIntArray;
+import android.util.TypedValue;
+import android.view.View;
+import com.android.settingslib.R;
+
+public class UsageGraph extends View {
+
+    private static final int PATH_DELIM = -1;
+
+    private final Paint mLinePaint;
+    private final Paint mFillPaint;
+    private final Paint mDottedPaint;
+
+    private final Drawable mDivider;
+    private final int mDividerSize;
+
+    private final Path mPath = new Path();
+
+    // Paths in coordinates they are passed in.
+    private final SparseIntArray mPaths = new SparseIntArray();
+    // Paths in local coordinates for drawing.
+    private final SparseIntArray mLocalPaths = new SparseIntArray();
+
+    private int mAccentColor;
+    private boolean mShowProjection;
+    private boolean mProjectUp;
+
+    private float mMaxX = 100;
+    private float mMaxY = 100;
+
+    public UsageGraph(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        final Resources resources = context.getResources();
+
+        mLinePaint = new Paint();
+        mLinePaint.setStyle(Style.STROKE);
+        mLinePaint.setStrokeCap(Cap.ROUND);
+        mLinePaint.setStrokeJoin(Join.ROUND);
+        mLinePaint.setAntiAlias(true);
+        mLinePaint.setPathEffect(new CornerPathEffect(resources.getDimensionPixelSize(
+                R.dimen.usage_graph_line_corner_radius)));
+        mLinePaint.setStrokeWidth(resources.getDimensionPixelSize(R.dimen.usage_graph_line_width));
+
+        mFillPaint = new Paint(mLinePaint);
+        mFillPaint.setStyle(Style.FILL);
+
+        mDottedPaint = new Paint(mLinePaint);
+        mDottedPaint.setStyle(Style.STROKE);
+        float dots = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_size);
+        float interval = resources.getDimensionPixelSize(R.dimen.usage_graph_dot_interval);
+        mDottedPaint.setStrokeWidth(dots * 3);
+        mDottedPaint.setPathEffect(new DashPathEffect(new float[] {dots, interval}, 0));
+        mDottedPaint.setColor(context.getColor(R.color.usage_graph_dots));
+
+        TypedValue v = new TypedValue();
+        context.getTheme().resolveAttribute(com.android.internal.R.attr.listDivider, v, true);
+        mDivider = context.getDrawable(v.resourceId);
+        mDividerSize = resources.getDimensionPixelSize(R.dimen.usage_graph_divider_size);
+    }
+
+    void clearPaths() {
+        mPaths.clear();
+    }
+
+    void setMax(int maxX, int maxY) {
+        mMaxX = maxX;
+        mMaxY = maxY;
+    }
+
+    public void addPath(SparseIntArray points) {
+        for (int i = 0; i < points.size(); i++) {
+            mPaths.put(points.keyAt(i), points.valueAt(i));
+        }
+        mPaths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM);
+        calculateLocalPaths();
+        postInvalidate();
+    }
+
+    void setAccentColor(int color) {
+        mAccentColor = color;
+        mLinePaint.setColor(mAccentColor);
+        updateGradient();
+        postInvalidate();
+    }
+
+    void setShowProjection(boolean showProjection, boolean projectUp) {
+        mShowProjection = showProjection;
+        mProjectUp = projectUp;
+        postInvalidate();
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        updateGradient();
+        calculateLocalPaths();
+    }
+
+    private void calculateLocalPaths() {
+        if (getWidth() == 0) return;
+        mLocalPaths.clear();
+        int pendingXLoc = 0;
+        int pendingYLoc = PATH_DELIM;
+        for (int i = 0; i < mPaths.size(); i++) {
+            int x = mPaths.keyAt(i);
+            int y = mPaths.valueAt(i);
+            if (y == PATH_DELIM) {
+                if (i == mPaths.size() - 1 && pendingYLoc != PATH_DELIM) {
+                    // Connect to the end of the graph.
+                    mLocalPaths.put(pendingXLoc, pendingYLoc);
+                }
+                // Clear out any pending points.
+                pendingYLoc = PATH_DELIM;
+                mLocalPaths.put(pendingXLoc + 1, PATH_DELIM);
+            } else {
+                final int lx = getX(x);
+                final int ly = getY(y);
+                pendingXLoc = lx;
+                if (mLocalPaths.size() > 0) {
+                    int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1);
+                    int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1);
+                    if (lastY != PATH_DELIM && (lastX == lx || lastY == ly)) {
+                        pendingYLoc = ly;
+                        continue;
+                    }
+                }
+                mLocalPaths.put(lx, ly);
+            }
+        }
+    }
+
+    private int getX(float x) {
+        return (int) (x / mMaxX * getWidth());
+    }
+
+    private int getY(float y) {
+        return (int) (getHeight() * (1 - (y / mMaxY)));
+    }
+
+    private void updateGradient() {
+        mFillPaint.setShader(new LinearGradient(0, 0, 0, getHeight(),
+                getColor(mAccentColor, .2f), 0, TileMode.CLAMP));
+    }
+
+    private int getColor(int color, float alphaScale) {
+        return (color & (((int) (0xff * alphaScale) << 24) | 0xffffff));
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        // Draw lines across the top, middle, and bottom.
+        drawDivider(0, canvas);
+        drawDivider((canvas.getHeight() - mDividerSize) / 2, canvas);
+        drawDivider(canvas.getHeight() - mDividerSize, canvas);
+
+        if (mLocalPaths.size() == 0) {
+            return;
+        }
+        if (mShowProjection) {
+            drawProjection(canvas);
+        }
+        drawFilledPath(canvas);
+        drawLinePath(canvas);
+    }
+
+    private void drawProjection(Canvas canvas) {
+        mPath.reset();
+        int x = mLocalPaths.keyAt(mLocalPaths.size() - 2);
+        int y = mLocalPaths.valueAt(mLocalPaths.size() - 2);
+        mPath.moveTo(x, y);
+        mPath.lineTo(canvas.getWidth(), mProjectUp ? 0 : canvas.getHeight());
+        canvas.drawPath(mPath, mDottedPaint);
+    }
+
+    private void drawLinePath(Canvas canvas) {
+        mPath.reset();
+        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
+        for (int i = 1; i < mLocalPaths.size(); i++) {
+            int x = mLocalPaths.keyAt(i);
+            int y = mLocalPaths.valueAt(i);
+            if (y == PATH_DELIM) {
+                if (++i < mLocalPaths.size()) {
+                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
+                }
+            } else {
+                mPath.lineTo(x, y);
+            }
+        }
+        canvas.drawPath(mPath, mLinePaint);
+    }
+
+    private void drawFilledPath(Canvas canvas) {
+        mPath.reset();
+        float lastStartX = mLocalPaths.keyAt(0);
+        mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0));
+        for (int i = 1; i < mLocalPaths.size(); i++) {
+            int x = mLocalPaths.keyAt(i);
+            int y = mLocalPaths.valueAt(i);
+            if (y == PATH_DELIM) {
+                mPath.lineTo(mLocalPaths.keyAt(i - 1), getHeight());
+                mPath.lineTo(lastStartX, getHeight());
+                mPath.close();
+                if (++i < mLocalPaths.size()) {
+                    lastStartX = mLocalPaths.keyAt(i);
+                    mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i));
+                }
+            } else {
+                mPath.lineTo(x, y);
+            }
+        }
+        canvas.drawPath(mPath, mFillPaint);
+    }
+
+    private void drawDivider(int y, Canvas canvas) {
+        mDivider.setBounds(0, y, canvas.getWidth(), y + mDividerSize);
+        mDivider.draw(canvas);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
new file mode 100644
index 0000000..f95a97a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.settingslib.graph;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.util.SparseIntArray;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.android.settingslib.R;
+
+public class UsageView extends FrameLayout {
+
+    private final UsageGraph mUsageGraph;
+    private final TextView[] mLabels;
+    private final TextView[] mBottomLabels;
+
+    public UsageView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        LayoutInflater.from(context).inflate(R.layout.usage_view, this);
+        mUsageGraph = (UsageGraph) findViewById(R.id.usage_graph);
+        mLabels = new TextView[] {
+                (TextView) findViewById(R.id.label_bottom),
+                (TextView) findViewById(R.id.label_middle),
+                (TextView) findViewById(R.id.label_top),
+        };
+        mBottomLabels = new TextView[] {
+                (TextView) findViewById(R.id.label_start),
+                (TextView) findViewById(R.id.label_end),
+        };
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.UsageView, 0, 0);
+        if (a.hasValue(R.styleable.UsageView_sideLabels)) {
+            setSideLabels(a.getTextArray(R.styleable.UsageView_sideLabels));
+        }
+        if (a.hasValue(R.styleable.UsageView_bottomLabels)) {
+            setBottomLabels(a.getTextArray(R.styleable.UsageView_bottomLabels));
+        }
+        if (a.hasValue(R.styleable.UsageView_textColor)) {
+            int color = a.getColor(R.styleable.UsageView_textColor, 0);
+            for (TextView v : mLabels) {
+                v.setTextColor(color);
+            }
+            for (TextView v : mBottomLabels) {
+                v.setTextColor(color);
+            }
+        }
+        if (a.hasValue(R.styleable.UsageView_android_gravity)) {
+            int gravity = a.getInt(R.styleable.UsageView_android_gravity, 0);
+            if (gravity == Gravity.END) {
+                LinearLayout layout = (LinearLayout) findViewById(R.id.graph_label_group);
+                LinearLayout labels = (LinearLayout) findViewById(R.id.label_group);
+                // Swap the children order.
+                layout.removeView(labels);
+                layout.addView(labels);
+                // Set gravity.
+                labels.setGravity(Gravity.END);
+                // Swap the bottom label padding
+                LinearLayout bottomLabels = (LinearLayout) findViewById(R.id.bottom_label_group);
+                bottomLabels.setPadding(bottomLabels.getPaddingRight(), bottomLabels.getPaddingTop(),
+                        bottomLabels.getPaddingLeft(), bottomLabels.getPaddingBottom());
+            } else if (gravity != Gravity.START) {
+                throw new IllegalArgumentException("Unsupported gravity " + gravity);
+            }
+        }
+        mUsageGraph.setAccentColor(a.getColor(R.styleable.UsageView_android_colorAccent, 0));
+    }
+
+    public void clearPaths() {
+        mUsageGraph.clearPaths();
+    }
+
+    public void addPath(SparseIntArray points) {
+        mUsageGraph.addPath(points);
+    }
+
+    public void configureGraph(int maxX, int maxY, boolean showProjection, boolean projectUp) {
+        mUsageGraph.setMax(maxX, maxY);
+        mUsageGraph.setShowProjection(showProjection, projectUp);
+    }
+
+    public void setAccentColor(int color) {
+        mUsageGraph.setAccentColor(color);
+    }
+
+    public void setSideLabels(CharSequence[] labels) {
+        if (labels.length != mLabels.length) {
+            throw new IllegalArgumentException("Invalid number of labels");
+        }
+        for (int i = 0; i < mLabels.length; i++) {
+            mLabels[i].setText(labels[i]);
+        }
+    }
+
+    public void setBottomLabels(CharSequence[] labels) {
+        if (labels.length != mBottomLabels.length) {
+            throw new IllegalArgumentException("Invalid number of labels");
+        }
+        for (int i = 0; i < mBottomLabels.length; i++) {
+            mBottomLabels[i].setText(labels[i]);
+        }
+    }
+
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index f03e94d..231fc69 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -63,14 +63,15 @@
                 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         List<AppOpsManager.PackageOps> appOps = aoManager.getPackagesForOps(LOCATION_OPS);
 
+        final int appOpsCount = appOps != null ? appOps.size() : 0;
+
         // Process the AppOps list and generate a preference list.
-        ArrayList<Request> requests = new ArrayList<>(appOps.size());
+        ArrayList<Request> requests = new ArrayList<>(appOpsCount);
         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) {
+        for (int i = 0; i < appOpsCount; ++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.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b270dd8..029a125 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -24,6 +24,8 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.net.Uri;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -34,6 +36,7 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.BackupUtils;
 import android.util.Log;
 
 import com.android.internal.widget.LockPatternUtils;
@@ -81,36 +84,49 @@
     private static final String KEY_GLOBAL = "global";
     private static final String KEY_LOCALE = "locale";
     private static final String KEY_LOCK_SETTINGS = "lock_settings";
+    private static final String KEY_SOFTAP_CONFIG = "softap_config";
+    private static final String KEY_NETWORK_POLICIES = "network_policies";
 
     // Versioning of the state file.  Increment this version
     // number any time the set of state items is altered.
-    private static final int STATE_VERSION = 4;
+    private static final int STATE_VERSION = 6;
+
+    // Versioning of the Network Policies backup payload.
+    private static final int NETWORK_POLICIES_BACKUP_VERSION = 1;
+
 
     // Slots in the checksum array.  Never insert new items in the middle
     // of this array; new slots must be appended.
-    private static final int STATE_SYSTEM          = 0;
-    private static final int STATE_SECURE          = 1;
-    private static final int STATE_LOCALE          = 2;
-    private static final int STATE_WIFI_SUPPLICANT = 3;
-    private static final int STATE_WIFI_CONFIG     = 4;
-    private static final int STATE_GLOBAL          = 5;
-    private static final int STATE_LOCK_SETTINGS   = 6;
+    private static final int STATE_SYSTEM           = 0;
+    private static final int STATE_SECURE           = 1;
+    private static final int STATE_LOCALE           = 2;
+    private static final int STATE_WIFI_SUPPLICANT  = 3;
+    private static final int STATE_WIFI_CONFIG      = 4;
+    private static final int STATE_GLOBAL           = 5;
+    private static final int STATE_LOCK_SETTINGS    = 6;
+    private static final int STATE_SOFTAP_CONFIG    = 7;
+    private static final int STATE_NETWORK_POLICIES = 8;
 
-    private static final int STATE_SIZE            = 7; // The current number of state items
+    private static final int STATE_SIZE             = 9; // The current number of state items
 
     // Number of entries in the checksum array at various version numbers
     private static final int STATE_SIZES[] = {
-        0,
-        4,              // version 1
-        5,              // version 2 added STATE_WIFI_CONFIG
-        6,              // version 3 added STATE_GLOBAL
-        STATE_SIZE      // version 4 added STATE_LOCK_SETTINGS
+            0,
+            4,              // version 1
+            5,              // version 2 added STATE_WIFI_CONFIG
+            6,              // version 3 added STATE_GLOBAL
+            7,              // version 4 added STATE_LOCK_SETTINGS
+            8,              // version 5 added STATE_SOFTAP_CONFIG
+            STATE_SIZE      // version 6 added STATE_NETWORK_POLICIES
     };
 
     // Versioning of the 'full backup' format
-    private static final int FULL_BACKUP_VERSION = 3;
+    // Increment this version any time a new item is added
+    private static final int FULL_BACKUP_VERSION = 5;
     private static final int FULL_BACKUP_ADDED_GLOBAL = 2;  // added the "global" entry
     private static final int FULL_BACKUP_ADDED_LOCK_SETTINGS = 3; // added the "lock_settings" entry
+    private static final int FULL_BACKUP_ADDED_SOFTAP_CONF = 4; //added the "softap_config" entry
+    private static final int FULL_BACKUP_ADDED_NETWORK_POLICIES = 5; //added "network_policies"
 
     private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;
 
@@ -119,8 +135,8 @@
     private static final String TAG = "SettingsBackupAgent";
 
     private static final String[] PROJECTION = {
-        Settings.NameValueTable.NAME,
-        Settings.NameValueTable.VALUE
+            Settings.NameValueTable.NAME,
+            Settings.NameValueTable.VALUE
     };
 
     private static final String FILE_WIFI_SUPPLICANT = "/data/misc/wifi/wpa_supplicant.conf";
@@ -146,7 +162,7 @@
 
     private SettingsHelper mSettingsHelper;
     private WifiManager mWfm;
-    private static String mWifiConfigFile;
+    private String mWifiConfigFile;
 
     // Chain of asynchronous operations used when rewriting the wifi supplicant config file
     WifiDisableRunnable mWifiDisable = null;
@@ -338,7 +354,7 @@
                                 }
                                 continue;
                             }
-                            if (! mKnownNetworks.contains(net)) {
+                            if (!mKnownNetworks.contains(net)) {
                                 if (DEBUG_BACKUP) {
                                     Log.v(TAG, "Adding " + net.ssid + " / " + net.key_mgmt);
                                 }
@@ -405,26 +421,34 @@
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
         byte[] wifiConfigData = getFileData(mWifiConfigFile);
+        byte[] softApConfigData = getSoftAPConfiguration();
+        byte[] netPoliciesData = getNetworkPolicies();
 
         long[] stateChecksums = readOldChecksums(oldState);
 
         stateChecksums[STATE_SYSTEM] =
-            writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
         stateChecksums[STATE_SECURE] =
-            writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
         stateChecksums[STATE_GLOBAL] =
-            writeIfChanged(stateChecksums[STATE_GLOBAL], KEY_GLOBAL, globalSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_GLOBAL], KEY_GLOBAL, globalSettingsData, data);
         stateChecksums[STATE_LOCALE] =
-            writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
+                writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
         stateChecksums[STATE_WIFI_SUPPLICANT] =
-            writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
-                    wifiSupplicantData, data);
+                writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
+                        wifiSupplicantData, data);
         stateChecksums[STATE_WIFI_CONFIG] =
-            writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
-                    data);
+                writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
+                        data);
         stateChecksums[STATE_LOCK_SETTINGS] =
-            writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS,
-                    lockSettingsData, data);
+                writeIfChanged(stateChecksums[STATE_LOCK_SETTINGS], KEY_LOCK_SETTINGS,
+                        lockSettingsData, data);
+        stateChecksums[STATE_SOFTAP_CONFIG] =
+                writeIfChanged(stateChecksums[STATE_SOFTAP_CONFIG], KEY_SOFTAP_CONFIG,
+                        softApConfigData, data);
+        stateChecksums[STATE_NETWORK_POLICIES] =
+                writeIfChanged(stateChecksums[STATE_NETWORK_POLICIES], KEY_NETWORK_POLICIES,
+                        netPoliciesData, data);
 
         writeNewChecksums(stateChecksums, newState);
     }
@@ -503,8 +527,8 @@
                     restoreWifiSupplicant(FILE_WIFI_SUPPLICANT,
                             restoredSupplicantData, restoredSupplicantData.length);
                     FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
-                            FileUtils.S_IRUSR | FileUtils.S_IWUSR |
-                            FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                            FileUtils.S_IRUSR | FileUtils.S_IWUSR
+                            | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                             Process.myUid(), Process.WIFI_UID);
                 }
                 if (restoredWifiConfigFile != null) {
@@ -516,8 +540,8 @@
                     Settings.Global.putInt(getContentResolver(),
                             Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, scanAlways);
                 }
-                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
-                        retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
+                enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED
+                        || retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
             }
         }
     }
@@ -542,27 +566,55 @@
         while (data.readNextHeader()) {
             final String key = data.getKey();
             final int size = data.getDataSize();
-            if (KEY_SYSTEM.equals(key)) {
-                restoreSettings(data, Settings.System.CONTENT_URI, movedToGlobal);
-                mSettingsHelper.applyAudioSettings();
-            } else if (KEY_SECURE.equals(key)) {
-                restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal);
-            } else if (KEY_GLOBAL.equals(key)) {
-                restoreSettings(data, Settings.Global.CONTENT_URI, null);
-            } else if (KEY_WIFI_SUPPLICANT.equals(key)) {
-                initWifiRestoreIfNecessary();
-                mWifiRestore.incorporateWifiSupplicant(data);
-            } else if (KEY_LOCALE.equals(key)) {
-                byte[] localeData = new byte[size];
-                data.readEntityData(localeData, 0, size);
-                mSettingsHelper.setLocaleData(localeData, size);
-            } else if (KEY_WIFI_CONFIG.equals(key)) {
-                initWifiRestoreIfNecessary();
-                mWifiRestore.incorporateWifiConfigFile(data);
-            } else if (KEY_LOCK_SETTINGS.equals(key)) {
-                restoreLockSettings(data);
-             } else {
-                data.skipEntityData();
+            switch (key) {
+                case KEY_SYSTEM :
+                    restoreSettings(data, Settings.System.CONTENT_URI, movedToGlobal);
+                    mSettingsHelper.applyAudioSettings();
+                    break;
+
+                case KEY_SECURE :
+                    restoreSettings(data, Settings.Secure.CONTENT_URI, movedToGlobal);
+                    break;
+
+                case KEY_GLOBAL :
+                    restoreSettings(data, Settings.Global.CONTENT_URI, null);
+                    break;
+
+                case KEY_WIFI_SUPPLICANT :
+                    initWifiRestoreIfNecessary();
+                    mWifiRestore.incorporateWifiSupplicant(data);
+                    break;
+
+                case KEY_LOCALE :
+                    byte[] localeData = new byte[size];
+                    data.readEntityData(localeData, 0, size);
+                    mSettingsHelper.setLocaleData(localeData, size);
+                    break;
+
+                case KEY_WIFI_CONFIG :
+                    initWifiRestoreIfNecessary();
+                    mWifiRestore.incorporateWifiConfigFile(data);
+                    break;
+
+                case KEY_LOCK_SETTINGS :
+                    restoreLockSettings(data);
+                    break;
+
+                case KEY_SOFTAP_CONFIG :
+                    byte[] softapData = new byte[size];
+                    data.readEntityData(softapData, 0, size);
+                    restoreSoftApConfiguration(softapData);
+                    break;
+
+                case KEY_NETWORK_POLICIES:
+                    byte[] netPoliciesData = new byte[size];
+                    data.readEntityData(netPoliciesData, 0, size);
+                    restoreNetworkPolicies(netPoliciesData);
+                    break;
+
+                default :
+                    data.skipEntityData();
+
             }
         }
 
@@ -589,6 +641,8 @@
         byte[] locale = mSettingsHelper.getLocaleData();
         byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
         byte[] wifiConfigData = getFileData(mWifiConfigFile);
+        byte[] softApConfigData = getSoftAPConfiguration();
+        byte[] netPoliciesData = getNetworkPolicies();
 
         // Write the data to the staging file, then emit that as our tarfile
         // representation of the backed-up settings.
@@ -605,16 +659,22 @@
             if (DEBUG_BACKUP) Log.d(TAG, systemSettingsData.length + " bytes of settings data");
             out.writeInt(systemSettingsData.length);
             out.write(systemSettingsData);
-            if (DEBUG_BACKUP) Log.d(TAG, secureSettingsData.length + " bytes of secure settings data");
+            if (DEBUG_BACKUP) {
+                Log.d(TAG, secureSettingsData.length + " bytes of secure settings data");
+            }
             out.writeInt(secureSettingsData.length);
             out.write(secureSettingsData);
-            if (DEBUG_BACKUP) Log.d(TAG, globalSettingsData.length + " bytes of global settings data");
+            if (DEBUG_BACKUP) {
+                Log.d(TAG, globalSettingsData.length + " bytes of global settings data");
+            }
             out.writeInt(globalSettingsData.length);
             out.write(globalSettingsData);
             if (DEBUG_BACKUP) Log.d(TAG, locale.length + " bytes of locale data");
             out.writeInt(locale.length);
             out.write(locale);
-            if (DEBUG_BACKUP) Log.d(TAG, wifiSupplicantData.length + " bytes of wifi supplicant data");
+            if (DEBUG_BACKUP) {
+                Log.d(TAG, wifiSupplicantData.length + " bytes of wifi supplicant data");
+            }
             out.writeInt(wifiSupplicantData.length);
             out.write(wifiSupplicantData);
             if (DEBUG_BACKUP) Log.d(TAG, wifiConfigData.length + " bytes of wifi config data");
@@ -623,6 +683,12 @@
             if (DEBUG_BACKUP) Log.d(TAG, lockSettingsData.length + " bytes of lock settings data");
             out.writeInt(lockSettingsData.length);
             out.write(lockSettingsData);
+            if (DEBUG_BACKUP) Log.d(TAG, softApConfigData.length + " bytes of softap config data");
+            out.writeInt(softApConfigData.length);
+            out.write(softApConfigData);
+            if (DEBUG_BACKUP) Log.d(TAG, netPoliciesData.length + " bytes of net policies data");
+            out.writeInt(netPoliciesData.length);
+            out.write(netPoliciesData);
 
             out.flush();    // also flushes downstream
 
@@ -691,12 +757,12 @@
             int retainedWifiState = enableWifi(false);
             restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, buffer, nBytes);
             FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
-                    FileUtils.S_IRUSR | FileUtils.S_IWUSR |
-                    FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+                    FileUtils.S_IRUSR | FileUtils.S_IWUSR
+                    | FileUtils.S_IRGRP | FileUtils.S_IWGRP,
                     Process.myUid(), Process.WIFI_UID);
             // retain the previous WIFI state.
-            enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
-                    retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
+            enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED
+                    || retainedWifiState == WifiManager.WIFI_STATE_ENABLING);
 
             // wifi config
             nBytes = in.readInt();
@@ -714,7 +780,26 @@
                     restoreLockSettings(buffer, nBytes);
                 }
             }
-
+            // softap config
+            if (version >= FULL_BACKUP_ADDED_SOFTAP_CONF) {
+                nBytes = in.readInt();
+                if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of softap config data");
+                if (nBytes > buffer.length) buffer = new byte[nBytes];
+                if (nBytes > 0) {
+                    in.readFully(buffer, 0, nBytes);
+                    restoreSoftApConfiguration(buffer);
+                }
+            }
+            // network policies
+            if (version >= FULL_BACKUP_ADDED_NETWORK_POLICIES) {
+                nBytes = in.readInt();
+                if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of network policies data");
+                if (nBytes > buffer.length) buffer = new byte[nBytes];
+                if (nBytes > 0) {
+                    in.readFully(buffer, 0, nBytes);
+                    restoreNetworkPolicies(buffer);
+                }
+            }
             if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete.");
         } else {
             data.close();
@@ -904,7 +989,7 @@
             settingsHelper.restoreValue(this, cr, contentValues, destination, key, value);
 
             if (DEBUG) {
-                Log.d(TAG, "Restored setting: " + destination + " : "+ key + "=" + value);
+                Log.d(TAG, "Restored setting: " + destination + " : " + key + "=" + value);
             }
         }
     }
@@ -1036,12 +1121,12 @@
 
             //Will truncate read on a very long file,
             //should not happen for a config file
-            byte[] bytes = new byte[(int)file.length()];
+            byte[] bytes = new byte[(int) file.length()];
 
             int offset = 0;
             int numRead = 0;
             while (offset < bytes.length
-                    && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+                    && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                 offset += numRead;
             }
 
@@ -1062,7 +1147,6 @@
                 }
             }
         }
-
     }
 
     private void restoreFileData(String filename, byte[] bytes, int size) {
@@ -1165,6 +1249,87 @@
         }
     }
 
+    private byte[] getSoftAPConfiguration() {
+        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        try {
+            return wifiManager.getWifiApConfiguration().getBytesForBackup();
+        } catch (IOException ioe) {
+            Log.e(TAG, "Failed to marshal SoftAPConfiguration" + ioe.getMessage());
+            return new byte[0];
+        }
+    }
+
+    private void restoreSoftApConfiguration(byte[] data) {
+        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+        try {
+            WifiConfiguration config = WifiConfiguration
+                    .getWifiConfigFromBackup(new DataInputStream(new ByteArrayInputStream(data)));
+            if (DEBUG) Log.d(TAG, "Successfully unMarshaled WifiConfiguration ");
+            wifiManager.setWifiApConfiguration(config);
+        } catch (IOException | BackupUtils.BadVersionException e) {
+            Log.e(TAG, "Failed to unMarshal SoftAPConfiguration " + e.getMessage());
+        }
+    }
+
+    private byte[] getNetworkPolicies() {
+        NetworkPolicyManager networkPolicyManager =
+                (NetworkPolicyManager) getSystemService(NETWORK_POLICY_SERVICE);
+        NetworkPolicy[] policies = networkPolicyManager.getNetworkPolicies();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        if (policies != null && policies.length != 0) {
+            DataOutputStream out = new DataOutputStream(baos);
+            try {
+                out.writeInt(NETWORK_POLICIES_BACKUP_VERSION);
+                out.writeInt(policies.length);
+                for (NetworkPolicy policy : policies) {
+                    if (policy != null) {
+                        byte[] marshaledPolicy = policy.getBytesForBackup();
+                        out.writeByte(BackupUtils.NOT_NULL);
+                        out.writeInt(marshaledPolicy.length);
+                        out.write(marshaledPolicy);
+                    } else {
+                        out.writeByte(BackupUtils.NULL);
+                    }
+                }
+            } catch (IOException ioe) {
+                Log.e(TAG, "Failed to convert NetworkPolicies to byte array " + ioe.getMessage());
+                baos.reset();
+            }
+        }
+        return baos.toByteArray();
+    }
+
+    private void restoreNetworkPolicies(byte[] data) {
+        NetworkPolicyManager networkPolicyManager =
+                (NetworkPolicyManager) getSystemService(NETWORK_POLICY_SERVICE);
+        if (data != null && data.length != 0) {
+            DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
+            try {
+                int version = in.readInt();
+                if (version < 1 || version > NETWORK_POLICIES_BACKUP_VERSION) {
+                    throw new BackupUtils.BadVersionException(
+                            "Unknown Backup Serialization Version");
+                }
+                int length = in.readInt();
+                NetworkPolicy[] policies = new NetworkPolicy[length];
+                for (int i = 0; i < length; i++) {
+                    byte isNull = in.readByte();
+                    if (isNull == BackupUtils.NULL) continue;
+                    int byteLength = in.readInt();
+                    byte[] policyData = new byte[byteLength];
+                    in.read(policyData, 0, byteLength);
+                    policies[i] = NetworkPolicy.getNetworkPolicyFromBackup(
+                            new DataInputStream(new ByteArrayInputStream(policyData)));
+                }
+                // Only set the policies if there was no error in the restore operation
+                networkPolicyManager.setNetworkPolicies(policies);
+            } catch (NullPointerException | IOException | BackupUtils.BadVersionException e) {
+                // NPE can be thrown when trying to instantiate a NetworkPolicy
+                Log.e(TAG, "Failed to convert byte array to NetworkPolicies " + e.getMessage());
+            }
+        }
+    }
+
     /**
      * Write an int in BigEndian into the byte array.
      * @param out byte array
@@ -1186,11 +1351,10 @@
     }
 
     private int readInt(byte[] in, int pos) {
-        int result =
-                ((in[pos    ] & 0xFF) << 24) |
-                ((in[pos + 1] & 0xFF) << 16) |
-                ((in[pos + 2] & 0xFF) <<  8) |
-                ((in[pos + 3] & 0xFF) <<  0);
+        int result = ((in[pos] & 0xFF) << 24)
+                | ((in[pos + 1] & 0xFF) << 16)
+                | ((in[pos + 2] & 0xFF) <<  8)
+                | ((in[pos + 3] & 0xFF) <<  0);
         return result;
     }
 
@@ -1207,4 +1371,4 @@
         }
         return WifiManager.WIFI_STATE_UNKNOWN;
     }
-}
+}
\ No newline at end of file
diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml
index b9a7c24..9d399c1 100644
--- a/packages/Shell/res/values-af/strings.xml
+++ b/packages/Shell/res/values-af/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Tuisskerm"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Foutverslag word tans gegenereer"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutverslag vasgevang"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Foutverslag <xliff:g id="ID">#%d</xliff:g> word tans geskep"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Foutverslag <xliff:g id="ID">#%d</xliff:g> is vasgevang"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Voeg tans besonderhede by die foutverslag"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Wag asseblief …"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swiep na links om jou foutverslag te deel"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak om jou foutverslag te deel"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tik om jou foutverslag te deel"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Foutverslae bevat data van die stelsel se verskillende loglêers af, insluitend persoonlike en private inligting. Deel foutverslae net met programme en mense wat jy vertrou."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Wys hierdie boodskap volgende keer"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutverslae"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"naamloos"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Besonderhede"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skermkiekie"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skermkiekie suksesvol geneem."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skermkiekie is suksesvol geneem."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kon nie skermkiekie neem nie."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Foutverslagbesonderhede"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Foutverslag <xliff:g id="ID">#%d</xliff:g> se besonderhede"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Lêernaam"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titel"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Gedetailleerde beskrywing"</string>
diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml
index 7c5519e..2545222 100644
--- a/packages/Shell/res/values-am/strings.xml
+++ b/packages/Shell/res/values-am/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ቀፎ"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"የሳንካ ሪፓርት እየመነጨ ነው"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"የሳንካ ሪፖርት ተይዟል"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> እየተመነጨ ነው"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ተወስዷል"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ዝርዝሮችን ወደ የሳንካ ሪፖርቱ በማከል ላይ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"እባክዎ ይጠብቁ…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"የሳንካ ሪፖርትዎን ለማጋራት ወደ ግራ ያንሸራትቱ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"የሳንካ ሪፖርትዎን ለማጋራት ይንክኩ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"የሳንካ ሪፖርትዎን ለማጋራት መታ ያድርጉ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"የሳንካ ሪፖርቶች የግል መረጃን ጨምሮ ከበርካታ የስርዓቱ ምዝግብ ማስታወሻዎች የመጣ ውሂብን ይዟል። የሳንካ ሪፖርቶች ለሚያምኗቸው መተግበሪያዎችን እና ሰዎችን ብቻ ያጋሩ።"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ይህን መልዕክት በሚቀጥለው ጊዜ አሳይ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"የሳንካ ሪፖርቶች"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ያልተሰየመ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ዝርዝሮች"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ቅጽበታዊ ገጽ እይታ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ቅጽበታዊ ገጽ እይታ በስኬት ተነስቷል።"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ቅጽበታዊ ገጽ እይታ በተሳካ ሁኔታ ተነስቷል"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ቅጽበታዊ ገጽ እይታ ሊነሳ አይችልም"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"የሳንካ ሪፖርት ዝርዝሮች"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ዝርዝሮች"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"የፋይል ስም"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ርዕስ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ዝርዝር መግለጫ"</string>
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
index b1079319..7593110 100644
--- a/packages/Shell/res/values-ar/strings.xml
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"جارٍ إنشاء تقرير الخطأ"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"تم الحصول على تقرير الأخطاء"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"جارٍ إنشاء تقرير الخطأ <xliff:g id="ID">#%d</xliff:g>."</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"تم تسجيل تقرير الخطأ <xliff:g id="ID">#%d</xliff:g>."</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"إضافة تفاصيل إلى تقرير الخطأ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"الرجاء الانتظار…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"مرر بسرعة لليمين لمشاركة تقرير الخطأ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"المس لمشاركة تقرير الأخطاء"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"انقر لمشاركة تقرير الخطأ."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"تحتوي تقارير الأخطاء على بيانات من ملفات سجلات النظام المتنوعة، بما في ذلك معلومات شخصية وخاصة. لا تشارك تقارير الأخطاء إلا مع التطبيقات والأشخاص الموثوق بهم."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"إظهار هذه الرسالة في المرة القادمة"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"تقارير الأخطاء"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"بدون اسم"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"التفاصيل"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"لقطة شاشة"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"تم التقاط لقطة الشاشة بنجاح."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"تم تسجيل لقطة الشاشة بنجاح."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"تعذر التقاط لقطة الشاشة."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"تفاصيل تقرير الخطأ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"تفاصيل تقرير الخطأ <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"اسم الملف"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"العنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"وصف تفصيلي"</string>
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
index d01ae2a..9130255 100644
--- a/packages/Shell/res/values-az-rAZ/strings.xml
+++ b/packages/Shell/res/values-az-rAZ/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bug hesabat yaradıldı"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Baq raport alındı"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> yaradıldı"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> alındı"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Detallar baq hesabatına əlavə olunur"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfən, gözləyin..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Baq raportunu paylaşmaq üçün sola sürüşdürün"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Xətanı şikayətini paylaşmaq üçün toxunun"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Baq hesabatınızı paylaşmaq üçün tıklayın"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Baq hesabatları"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"adsız"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detallar"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"displey görüntüsü"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Displey görüntüsü uğurla çəkildi."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Displey görüntüsü uğurla çəkildi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Displey görüntüsü əlçatan deyil."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Baq hesabat detalları"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> detalları"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Fayl adı"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Başlıq"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ətraflı təsvir"</string>
diff --git a/packages/Shell/res/values-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml
index f39dbcb..597e545 100644
--- a/packages/Shell/res/values-b+sr+Latn/strings.xml
+++ b/packages/Shell/res/values-b+sr+Latn/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Izveštaj o grešci se generiše"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Izveštaj o grešci je snimljen"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> se generiše"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prevucite ulevo da biste delili izveštaj o greškama"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Dodirnite da biste delili izveštaj o grešci"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, uključujući lične i privatne podatke. Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži ovu poruku sledeći put"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izveštaji o greškama"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalji"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snimci ekrana"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snimanje ekrana je uspelo."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snimak ekrana je napravljen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje ekrana nije uspelo."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalji izveštaja o grešci"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalji izveštaja o grešci <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Naziv datoteke"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Naslov"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljni opis"</string>
diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml
index 068bcd3..6ca7914 100644
--- a/packages/Shell/res/values-bg/strings.xml
+++ b/packages/Shell/res/values-bg/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Команден ред"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Сигналът за програмна грешка се генерира"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Отчетът за програмни грешки е записан"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ се генерира"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ е заснет"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Подробностите се добавят към сигнала за пр. грешка"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Моля, изчакайте…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Прекарайте пръст наляво, за да споделите сигнала си за програмна грешка"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Докоснете, за да споделите отчета си за програмни грешки"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Докоснете, за да споделите сигнала си за програмна грешка"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Отчетите за програмни грешки съдържат данни от различни регистрационни файлове на системата, включително лична и поверителна информация. Споделяйте ги само с приложения и хора, на които имате доверие."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Това съобщение да се показва следващия път"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчети за прогр. грешки"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"без име"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Подробности"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Екранна снимка"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Екранната снимка бе направена успешно."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Екранната снимка бе направена успешно."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Екранната снимка не можа да бъде направена."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Подробности за сигнала за програмна грешка"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Подробности за сигнала за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Име на файла"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Заглавие"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробно описание"</string>
diff --git a/packages/Shell/res/values-bn-rBD/strings.xml b/packages/Shell/res/values-bn-rBD/strings.xml
index a973586..5390315 100644
--- a/packages/Shell/res/values-bn-rBD/strings.xml
+++ b/packages/Shell/res/values-bn-rBD/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"শেল"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ত্রুটির প্রতিবেদন তৈরি করা হচ্ছে"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ত্রুটির প্রতিবেদন নেওয়া হয়েছে"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> তৈরি করা হচ্ছে"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> ক্যাপচার করা হয়েছে"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ত্রুটির প্রতিবেদনে বিশদ বিবরণ যোগ করা হচ্ছে"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"অনুগ্রহ করে অপেক্ষা করুন..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"আপনার বাগ রিপোর্ট শেয়ার করতে বামে সোয়াইপ করুন"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"আপনার ত্রুটির প্রতিবেদন শেয়ার করতে স্পর্শ করুন"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"আপনার ত্রুটির প্রতিবেদন শেয়ার করতে আলতো চাপ দিন"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ত্রুটির প্রতিবেদনগুলিতে থাকা ডেটা, সিস্টেমের বিভিন্ন লগ ফাইলগুলি থেকে আসে, যাতে ব্যক্তিগত এবং গোপনীয় তথ্য অন্তর্ভুক্ত থাকে৷ আপনি বিশ্বাস করেন শুধুমাত্র এমন অ্যাপ্লিকেশান এবং ব্যক্তিদের সাথে ত্রুটির প্রতিবেদনগুলি ভাগ করুন৷"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"এই বার্তাটি পরের বার দেখান"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ত্রুটির প্রতিবেদনগুলি"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"নামবিহীন"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"বিশদ বিবরণ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"স্ক্রীনশট"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"স্ক্রীনশট সফলভাবে নেওয়া হয়েছে৷"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"স্ক্রীনশট সফলভাবে নেওয়া হয়েছে৷"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"স্ক্রীনশট নেওয়া যায়নি৷"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ত্রুটি প্রতিবেদনের বিবরণ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ত্রুটির প্রতিবেদন <xliff:g id="ID">#%d</xliff:g> এর বিশদ বিবরণ"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ফাইলের নাম"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"শীর্ষক"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"বিস্তারিত বিবরণ"</string>
diff --git a/packages/Shell/res/values-bs-rBA/strings.xml b/packages/Shell/res/values-bs-rBA/strings.xml
index 55a9341..903c2ab 100644
--- a/packages/Shell/res/values-bs-rBA/strings.xml
+++ b/packages/Shell/res/values-bs-rBA/strings.xml
@@ -16,42 +16,24 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for app_label (3701846017049540910) -->
-    <skip />
-    <!-- no translation found for bugreport_in_progress_title (7409917338223386637) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_title (2293711546892863898) -->
-    <skip />
+    <string name="app_label" msgid="3701846017049540910">"Ljuska"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> se generira"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
-    <!-- no translation found for bugreport_finished_text (8389172248433597683) -->
-    <skip />
-    <!-- no translation found for bugreport_finished_text (3559904746859400732) -->
-    <skip />
-    <!-- no translation found for bugreport_confirm (5130698467795669780) -->
-    <skip />
-    <!-- no translation found for bugreport_confirm_repeat (4926842460688645058) -->
-    <skip />
-    <!-- no translation found for bugreport_storage_title (5332488144740527109) -->
-    <skip />
-    <!-- no translation found for bugreport_unreadable_text (586517851044535486) -->
-    <skip />
-    <!-- no translation found for bugreport_unnamed (2800582406842092709) -->
-    <skip />
-    <!-- no translation found for bugreport_info_action (2158204228510576227) -->
-    <skip />
-    <!-- no translation found for bugreport_screenshot_action (8677781721940614995) -->
-    <skip />
-    <!-- no translation found for bugreport_screenshot_taken (7175343181767429088) -->
-    <skip />
-    <!-- no translation found for bugreport_screenshot_failed (5853049140806834601) -->
-    <skip />
-    <!-- no translation found for bugreport_info_dialog_title (3113549839798564645) -->
-    <skip />
-    <!-- no translation found for bugreport_info_name (4414036021935139527) -->
-    <skip />
-    <!-- no translation found for bugreport_info_title (5599558206004371052) -->
-    <skip />
-    <!-- no translation found for bugreport_info_description (4117088998733546784) -->
-    <skip />
+    <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prevucite lijevo da podijelite izvještaj o greškama"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema, uključujući lične i privatne informacije. Podijelite izvještaje o greškama samo sa aplikacijama i osobama kojima vjerujete."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži ovu poruku sljedeći put"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string>
+    <string name="bugreport_unreadable_text" msgid="586517851044535486">"Nije moguće pročitati izvještaj o grešci"</string>
+    <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
+    <string name="bugreport_info_action" msgid="2158204228510576227">"Detalji"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snimak ekrana"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Ekran je uspješno snimljen."</string>
+    <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekran nije moguće snimiti."</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalji izvještaja o grešci <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_info_name" msgid="4414036021935139527">"Naziv fajla"</string>
+    <string name="bugreport_info_title" msgid="5599558206004371052">"Naslov"</string>
+    <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljan opis"</string>
 </resources>
diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml
index 14c21da..0836946 100644
--- a/packages/Shell/res/values-ca/strings.xml
+++ b/packages/Shell/res/values-ca/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Protecció"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"S\'està generant l\'informe d\'errors"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"S\'ha registrat l\'informe d\'error"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"S\'està generant l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"S\'ha capturat l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"S\'estan afegint detalls a l\'informe d\'errors"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Llisca cap a l\'esquerra per compartir l\'informe d\'errors."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca aquí per compartir el teu informe d\'error."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca per compartir l\'informe d\'errors"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Els informes d\'error contenen dades dels diferents fitxers de registre del sistema, inclosa informació privada i personal. Comparteix els informes d\'error només amb les aplicacions i amb les persones en qui confies."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra aquest missatge la propera vegada"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'error"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sense nom"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalls"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla s\'ha fet correctament."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"La captura de pantalla s\'ha fet correctament."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No s\'ha pogut fer la captura de pantalla."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalls de l\'informe d\'errors"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalls de l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nom del fitxer"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Títol"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripció detallada"</string>
diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index 19a4453..215ec87 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Vytváří se zpráva o chybě"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bylo vytvořeno chybové hlášení"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> se vytváří"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> byla vytvořena"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Přidávání podrobností do zprávy o chybě"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Čekejte prosím…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Chcete-li hlášení chyby sdílet, přejeďte doleva."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Chybové hlášení můžete sdílet klepnutím."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Zprávu o chybě můžete sdílet klepnutím"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Chybová hlášení obsahují data z různých souborů protokolů systému včetně osobních a soukromých informací. Chybová hlášení sdílejte pouze s aplikacemi a uživateli, kterým důvěřujete."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobrazit tuto zprávu příště"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Zprávy o chybách"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"bez názvu"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Podrobnosti"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snímek obrazovky"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímek obrazovky byl úspěšně pořízen."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snímek obrazovky byl úspěšně pořízen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímek obrazovky se nepodařilo pořídit."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti zprávy o chybě"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Podrobnosti zprávy o chybě <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Název souboru"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Název"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podrobný popis"</string>
diff --git a/packages/Shell/res/values-da/strings.xml b/packages/Shell/res/values-da/strings.xml
index a03276a..e956d3a 100644
--- a/packages/Shell/res/values-da/strings.xml
+++ b/packages/Shell/res/values-da/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Fejlrapport genereres"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Fejlrapporten er registreret"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Fejlrapporten <xliff:g id="ID">#%d</xliff:g> genereres"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Fejrapporten <xliff:g id="ID">#%d</xliff:g> blev gemt"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Tilføjelse af oplysninger til fejlrapporten"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vent et øjeblik…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Stryg til venstre for at dele din fejlrapport"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tryk for at dele din fejlrapport"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tryk for at dele din fejlrapport"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Fejlrapporter indeholder data fra systemets forskellige logfiler, f.eks. personlige og private oplysninger. Del kun fejlrapporter med apps og personer, du har tillid til."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne underretning næste gang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Fejlrapporter"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ikke navngivet"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Oplysninger"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skærmbillede"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Der blev taget et skærmbillede."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Der blev taget et skærmbillede."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Der kunne ikke tages et skærmbillede."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Fejlrapportoplysninger"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Oplysninger om fejlrapporten <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filnavn"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titel"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljeret beskrivelse"</string>
diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml
index 4f5e6c5..07f8898 100644
--- a/packages/Shell/res/values-de/strings.xml
+++ b/packages/Shell/res/values-de/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Fehlerbericht wird generiert"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Fehlerbericht erfasst"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Fehlerbericht <xliff:g id="ID">#%d</xliff:g> wird generiert"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Fehlerbericht <xliff:g id="ID">#%d</xliff:g> erfasst"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Informationen werden zum Fehlerbericht hinzugefügt"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Bitte warten…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Wische nach links, um deinen Fehlerbericht zu teilen."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tippen, um Fehlerbericht zu teilen"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Zum Teilen des Fehlerberichts tippen"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Fehlerberichte enthalten Daten aus verschiedenen Protokolldateien des Systems, darunter auch personenbezogene und private Daten. Teile Fehlerberichte nur mit Apps und Personen, denen du vertraust."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Diese Nachricht nächstes Mal zeigen"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Fehlerberichte"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"Unbenannt"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot wurde aufgenommen."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot wurde aufgenommen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot konnte nicht aufgenommen werden."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details des Fehlerberichts"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Details zum Fehlerbericht <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Dateiname"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titel"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaillierte Beschreibung"</string>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
index 71debd7..6746976 100644
--- a/packages/Shell/res/values-el/strings.xml
+++ b/packages/Shell/res/values-el/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Κέλυφος"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Δημιουργείται αναφορά σφάλματος"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Η λήψη της αναφοράς ήταν επιτυχής"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Δημιουργείται η αναφορά σφάλματος <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Έγινε λήψη της αναφοράς σφάλματος <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Προσθήκη λεπτομερειών στην αναφορά σφάλματος"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Περιμένετε…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Σύρετε προς τα αριστερά για κοινή χρήση της αναφοράς σφαλμάτων"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Αγγίξτε για να μοιραστείτε τη αναφορά σφαλμάτων"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Πατήστε για κοινή χρήση της αναφοράς σφάλματος"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Οι αναφορές σφαλμάτων περιέχουν δεδομένα από τα διάφορα αρχεία καταγραφής του συστήματος, συμπεριλαμβανομένων προσωπικών και ιδιωτικών πληροφοριών. Να μοιράζεστε αναφορές σφαλμάτων μόνο με εφαρμογές και άτομα που εμπιστεύεστε."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Εμφάνιση αυτού του μηνύματος την επόμενη φορά"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Αναφορές σφαλμάτων"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ανώνυμη"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Λεπτομέρειες"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Στιγμιότυπο οθόνης"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Η λήψη του στιγμιότυπου οθόνης ολοκληρώθηκε με επιτυχία."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Η λήψη του στιγμιότυπου οθόνης ολοκληρώθηκε με επιτυχία."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Δεν ήταν δυνατή η λήψη του στιγμιότυπου οθόνης."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Λεπτομέρειες αναφοράς σφαλμάτων"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Λεπτομέρειες της αναφοράς σφάλματος <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Όνομα αρχείου"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Τίτλος"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Αναλυτική περιγραφή"</string>
diff --git a/packages/Shell/res/values-en-rAU/strings.xml b/packages/Shell/res/values-en-rAU/strings.xml
index a1bd979..ac681e2 100644
--- a/packages/Shell/res/values-en-rAU/strings.xml
+++ b/packages/Shell/res/values-en-rAU/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bug report is being generated"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"unnamed"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Bug report <xliff:g id="ID">#%d</xliff:g> details"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filename"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Title"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
diff --git a/packages/Shell/res/values-en-rGB/strings.xml b/packages/Shell/res/values-en-rGB/strings.xml
index a1bd979..ac681e2 100644
--- a/packages/Shell/res/values-en-rGB/strings.xml
+++ b/packages/Shell/res/values-en-rGB/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bug report is being generated"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"unnamed"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Bug report <xliff:g id="ID">#%d</xliff:g> details"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filename"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Title"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
diff --git a/packages/Shell/res/values-en-rIN/strings.xml b/packages/Shell/res/values-en-rIN/strings.xml
index a1bd979..ac681e2 100644
--- a/packages/Shell/res/values-en-rIN/strings.xml
+++ b/packages/Shell/res/values-en-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bug report is being generated"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bug report captured"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Touch to share your bug report"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"unnamed"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot taken successfully."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot taken successfully."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot could not be taken."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Bug report details"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Bug report <xliff:g id="ID">#%d</xliff:g> details"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filename"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Title"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detailed description"</string>
diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml
index f86fea0..96ca14c 100644
--- a/packages/Shell/res/values-es-rUS/strings.xml
+++ b/packages/Shell/res/values-es-rUS/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"El informe de errores se está generando"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de errores capturado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Se está generando el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Se capturó el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Agregando detalles al informe de errores"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de errores."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca para compartir tu informe de errores."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir el informe de errores"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida la información personal y privada. Comparte los informes de errores únicamente con aplicaciones y personas en las que confíes."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de errores"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sin nombre"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalles"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Se tomó la captura de pantalla correctamente."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Se tomó la captura de pantalla correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se pudo tomar la captura de pantalla."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalles del informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nombre del archivo"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripción completa"</string>
diff --git a/packages/Shell/res/values-es/strings.xml b/packages/Shell/res/values-es/strings.xml
index 8f6cdeb..00874c6 100644
--- a/packages/Shell/res/values-es/strings.xml
+++ b/packages/Shell/res/values-es/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Se está generando el informe de errores"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de error registrado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Se está generando el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Informe de errores <xliff:g id="ID">#%d</xliff:g> capturado"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Añadiendo detalles al informe de errores"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de error"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca para compartir tu informe de error"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir el informe de errores"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida información personal y privada. Comparte los informes de errores únicamente con aplicaciones y usuarios en los que confíes."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de error"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sin nombre"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalles"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La captura de pantalla se ha realizado correctamente."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Captura de pantalla realizada correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"No se puede realizar la captura de pantalla."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles del informe de errores"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalles del informe de errores <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nombre de archivo"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descripción completa"</string>
diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
index 3ebd56d..bc469bc 100644
--- a/packages/Shell/res/values-et-rEE/strings.xml
+++ b/packages/Shell/res/values-et-rEE/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kest"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Veaaruande loomine"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Veaaruanne jäädvustati"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luuakse veaaruannet <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Jäädvustati veaaruanne <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Üksikasjade lisamine veaaruandesse"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Oodake …"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veaaruande jagamiseks pühkige vasakule"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Veaaruande jagamiseks puudutage"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Veaaruande jagamiseks puudutage"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Veaaruanded sisaldavad andmeid erinevatest süsteemi logifailidest, sh isiklikku ja privaatset teavet. Jagage veaaruandeid ainult usaldusväärsete rakenduste ja inimestega."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Kuva see sõnum järgmisel korral"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Veaaruanded"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"nimeta"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Üksikasjad"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Ekraanipilt"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekraanipildi tegemine õnnestus."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Ekraanipildi jäädvustamine õnnestus."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekraanipilti ei saanud teha."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Veaaruande üksikasjad"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Veaaruande <xliff:g id="ID">#%d</xliff:g> üksikasjad"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Faili nimi"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Pealkiri"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Üksikasjalik kirjeldus"</string>
diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml
index 93fdb60..614f17e 100644
--- a/packages/Shell/res/values-eu-rES/strings.xml
+++ b/packages/Shell/res/values-eu-rES/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell-interfazea"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Sortzen ari gara akatsen txostena"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Akatsen txostena jaso da"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egiten ari gara"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egin da"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Akatsen txostenean xehetasunak gehitzen"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Itxaron, mesedez…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Programa-akatsen txostena partekatzeko, pasatu hatza ezkerrera"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Akatsen txostena partekatzeko, ukitu"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Sakatu akatsen txostena partekatzeko"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Akatsen txostenek sistemaren erregistro-fitxategietako datuak dauzkate, informazio pertsonala eta pribatua barne. Akatsen txostenak partekatzen badituzu, partekatu soilik aplikazio eta pertsona fidagarriekin."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Erakutsi mezu hau hurrengoan"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Akatsen txostenak"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"izengabea"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Xehetasunak"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Pantaila-argazkia"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Atera da pantaila-argazkia."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Atera da pantaila-argazkia."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ezin izan da atera pantaila-argazkia."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Akatsen txostenaren xehetasunak"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostenaren xehetasunak"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Fitxategi-izena"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Izena"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Azalpen xehatua"</string>
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index c4ec8b4..ab00562 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"گزارش اشکال در حال ایجاد شدن است"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"گزارش اشکال دریافت شد"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> در حال ایجاد شدن است"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> ثبت شد"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"اضافه کردن جزئیات به گزارش اشکال"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"لطفاً منتظر بمانید..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"برای اشتراک‌گذاری گزارش اشکال، به تندی آن را به چپ بکشید"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"جهت اشتراک‌گذاری گزارش اشکال خود لمس کنید"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای به اشتراک گذاشتن گزارش اشکال، ضربه بزنید"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"گزارش‌های اشکال حاوی داده‌هایی از فایل‌های گزارش مختلف در سیستم هستند، شامل اطلاعات شخصی و خصوصی. گزارش‌های اشکال را فقط با افراد و برنامه‌های مورد اعتماد خود به اشتراک بگذارید."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"دفعه بعد این پیام نشان داده شود"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"بی‌نام"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"جزئیات"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"عکس صفحه‌نمایش"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"عکس صفحه‌نمایش با موفقیت گرفته شد."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"عکس صفحه‌نمایش با موفقیت گرفته شد."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"نمی‌توان عکس صفحه‌نمایش گرفت."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"جزئیات گزارش اشکال"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"جزئیات گزارش اشکال <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"نام فایل"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"عنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"جزئیات دقیق"</string>
diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml
index 0fc4b77..be7aabd 100644
--- a/packages/Shell/res/values-fi/strings.xml
+++ b/packages/Shell/res/values-fi/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Komentotulkki"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Luodaan virheraporttia"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Virheraportti tallennettu"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luodaan virheraporttia <xliff:g id="ID">#%d</xliff:g>."</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Virheraportti <xliff:g id="ID">#%d</xliff:g> tallennettu"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Lisätään tietoja virheraporttiin"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Odota…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Jaa virheraportti pyyhkäisemällä vasemmalle"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Jaa virheraportti koskettamalla tätä"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Jaa virheraportti napauttamalla."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Virheraportit sisältävät järjestelmän lokitietoja, ja niihin voi sisältyä henkilökohtaisia ja yksityisiä tietoja. Jaa virheraportteja vain luotettaville sovelluksille ja käyttäjille."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Näytä tämä viesti seuraavalla kerralla"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Virheraportit"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"nimetön"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Tietoja"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Kuvakaappaus"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Kuvakaappaus tallennettu."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Kuvakaappaus on tallennettu."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Kuvakaappauksen tallentaminen epäonnistui."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Virheraportin tiedot"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Virheraportin <xliff:g id="ID">#%d</xliff:g> tiedot"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Tiedostonimi"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Otsikko"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Yksityiskohtainen kuvaus"</string>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index d2ef54c..7d9f97d 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Le rapport de bogue est en cours de création"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bogue enregistré"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> généré"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> enregistré"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout de détails au rapport de bogue"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport de bogue."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Appuyer ici pour partager votre rapport de bogue"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Touchez ici pour partager votre rapport de bogue"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bogue qu\'avec les applications et les personnes que vous estimez fiables."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sans nom"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Détails"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Saisie d\'écran"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La saisie d\'écran a réussi."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"La saisie d\'écran a réussi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Une erreur s\'est produite lors de la saisie d\'écran."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bogue"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Détails du rapport de bogue <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nom de fichier"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titre"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Description détaillée"</string>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index ca135ed..74025d9 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Le rapport de bug est en cours de création."</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Rapport de bug enregistré"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" est en cours de création"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" a bien été enregistré"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout d\'informations au rapport de bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport d\'erreur."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Appuyez ici pour partager le rapport de bug"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Appuyer pour partager votre rapport de bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bug contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bug qu\'avec les applications et les personnes que vous estimez fiables."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports d\'erreur"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sans nom"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Détails"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captures d\'écran"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"La capture d\'écran a bien été effectuée."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"La capture d\'écran a bien été effectuée."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossible d\'effectuer une capture d\'écran."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Détails du rapport de bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Informations sur le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\""</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nom de fichier"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titre"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Description détaillée"</string>
diff --git a/packages/Shell/res/values-gl-rES/strings.xml b/packages/Shell/res/values-gl-rES/strings.xml
index 612d346..d3be7c5 100644
--- a/packages/Shell/res/values-gl-rES/strings.xml
+++ b/packages/Shell/res/values-gl-rES/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Estase xerando o informe de erro"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Informe de erros rexistrado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Estase xerando o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Rexistrouse o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Engadindo detalles ao informe de erro"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Agarda..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Pasa o dedo á esquerda para compartir o teu informe de erros"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toca aquí para compartir o teu informe de erros"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir o teu informe de erros"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os informes de erros conteñen datos dos distintos ficheiros de rexistro do sistema, incluída información persoal e privada. Comparte os informes de erros unicamente con aplicacións e persoas de confianza."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensaxe a próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de erros"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sen nome"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalles"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de pantalla"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"A captura de pantalla realizouse correctamente."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"A captura de pantalla realizouse correctamente."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Non se puido realizar a captura de pantalla."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalles do informe de erros"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalles do informe de erros <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nome do ficheiro"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrición detallada"</string>
diff --git a/packages/Shell/res/values-gu-rIN/strings.xml b/packages/Shell/res/values-gu-rIN/strings.xml
index 7baefe7..45df7b3 100644
--- a/packages/Shell/res/values-gu-rIN/strings.xml
+++ b/packages/Shell/res/values-gu-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"શેલ"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"બગ રિપોર્ટ જનરેટ કરવામાં આવી રહી છે"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"બગ રિપોર્ટ કેપ્ચર કરી"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"બગ રિપોર્ટ <xliff:g id="ID">#%d</xliff:g> જનરેટ કરવામાં આવી રહી છે"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"બગ રિપોર્ટ <xliff:g id="ID">#%d</xliff:g> કૅપ્ચર કરી"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"બગ રિપોર્ટમાં વિગતો ઉમેરવી"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"કૃપા કરીને રાહ જુઓ…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"તમારી બગ રિપોર્ટ શેર કરવા માટે ડાબે સ્વાઇપ કરો"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"તમારી બગ રિપોર્ટ શેર કરવા માટે ટચ કરો"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"તમારી બગ રિપોર્ટ શેર કરવા ટૅપ કરો"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"બગ રિપોર્ટ્સ વ્યક્તિગત અને ખાનગી માહિતી સહિત, સિસ્ટમની વિભિન્ન લૉગ ફાઇલોનો ડેટા ધરાવે છે. બગ રિપોર્ટ્સ ફક્ત તમે વિશ્વાસ કરતા હો તે એપ્લિકેશનો અને લોકો સાથે જ શેર કરો."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"આગલી વખતે આ સંદેશ બતાવો"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"બગ રિપોર્ટ્સ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"અનામાંકિત"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"વિગતો"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"સ્ક્રીનશોટ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"સ્ક્રીનશોટ સફળતાપૂર્વક લેવાયો."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"સ્ક્રીનશોટ સફળતાપૂર્વક લેવાયો."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"સ્ક્રીનશોટ લઇ શકાયો નથી."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"બગ રિપોર્ટની વિગતો"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"બગ રિપોર્ટ <xliff:g id="ID">#%d</xliff:g> ની વિગતો"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ફાઇલનું નામ"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"શીર્ષક"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"વિગતવાર વર્ણન"</string>
diff --git a/packages/Shell/res/values-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
index c21213e..8858bc3 100644
--- a/packages/Shell/res/values-hi/strings.xml
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"शेल"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"बग रिपोर्ट जेनरेट हो रही है"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"बग रिपोर्ट कैप्चर कर ली गई"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> जेनरेट की जा रही है"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> कैप्चर की गई"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"बग रिपोर्ट में विवरण जोड़े जा रहे हैं"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करें…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"अपनी बग रिपोर्ट साझा करने के लिए बाएं स्वाइप करें"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"अपनी बग रिपोर्ट साझा करने के लिए स्पर्श करें"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"अपनी बग रिपोर्ट साझा करने के लिए टैप करें"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"बग रिपोर्ट में व्यक्तिगत और निजी जानकारी सहित, सिस्टम की विभिन्न लॉग फ़ाइलों का डेटा होता है. बग रिपोर्ट केवल विश्वसनीय ऐप्स  और व्यक्तियों से ही साझा करें."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यह संदेश अगली बार दिखाएं"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रिपोर्ट"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामांकित"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"विवरण"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट सफलतापूर्वक लिया गया."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट सफलतापूर्वक लिया गया."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट नहीं लिया जा सका."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्ट के विवरण"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g> के विवरण"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"फ़ाइल नाम"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत वर्णन"</string>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
index 810ad3a..cb03f9c 100644
--- a/packages/Shell/res/values-hr/strings.xml
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Ljuska"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Generira se izvješće o programskoj pogrešci"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Prijava programske pogreške snimljena je"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generira se izvješće o programskoj pogrešci <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Izvješće o programskoj pogrešci <xliff:g id="ID">#%d</xliff:g> snimljeno"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje pojedinosti u izvješće o progr. pogrešci"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prijeđite prstom ulijevo da biste poslali izvješće o programskim pogreškama"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Dodirnite za dijeljenje prijave programske pogreške"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvješće o programskoj pogrešci"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Prijave programskih pogrešaka sadržavaju podatke iz različitih datoteka zapisnika sustava, uključujući osobne i privatne informacije. Prijave programskih pogrešaka dijelite samo s aplikacijama i osobama koje smatrate pouzdanima."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži tu poruku sljedeći put"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvj. o prog. pogreš."</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"bez naziva"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Pojedinosti"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snimka zaslona"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zaslon je snimljen."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snimka zaslona uspješno izrađena."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snimanje zaslona nije uspjelo."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Pojedinosti izvješća o programskoj pogrešci"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Pojedinosti izvješća o programskoj pogrešci <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Naziv datoteke"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Naslov"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljan opis"</string>
diff --git a/packages/Shell/res/values-hu/strings.xml b/packages/Shell/res/values-hu/strings.xml
index b78fc61..390cd2f 100644
--- a/packages/Shell/res/values-hu/strings.xml
+++ b/packages/Shell/res/values-hu/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Héj"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Hibajelentés létrehozása folyamatban"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Programhiba-jelentés rögzítve"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) létrehozása folyamatban"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) rögzítve"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Információk hozzáadása a hibajelentéshez"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Kérjük, várjon..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Húzza ujját balra a hibajelentés megosztásához"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Érintse meg a programhiba-jelentés megosztásához"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Koppintson a hibajelentés megosztásához"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"A programhiba-jelentések a rendszer különféle naplófájljaiból származó adatokat tartalmaznak, köztük személyes és magánjellegű információkat is. Csak olyan alkalmazásokkal és személyekkel osszon meg programhiba-jelentéseket, amelyekben vagy akikben megbízik."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Üzenet mutatása legközelebb"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hibajelentések"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"névtelen"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Részletek"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Képernyőkép"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Sikerült elkészíteni a képernyőképet."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Képernyőkép sikeresen rögzítve."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nem sikerült elkészíteni a képernyőképet."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hibajelentés részletei"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) részletei"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Fájlnév"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Név"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Részletes leírás"</string>
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index 4912d54..68478ab 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Խեցի"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Վրիպակի զեկույցը ստեղծվում է"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց է ստացվել"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը ստեղծվում է"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը գրանցվեց"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Տվյալների ավելացում վրիպակի զեկույցում"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Խնդրում ենք սպասել…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Հպեք՝ վրիպակի զեկույցը տրամադրելու համար"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական ​​և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Վրիպակների հաշվետվություններ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"անանուն"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Մանրամասներ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Էկրանի պատկեր"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Էկրանի պատկերը հաջողությամբ ստացվեց:"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Էկրանի պատկերը հաջողությամբ ստացվեց:"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Չհաջողվեց ստանալ էկրանի պատկերը:"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Վրիպակի զեկույցի մանրամասները"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցի մանրամասները"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Ֆայլի անունը"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Անվանումը"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Մանրամասն նկարագրություն"</string>
diff --git a/packages/Shell/res/values-in/strings.xml b/packages/Shell/res/values-in/strings.xml
index e774de9..4416fc7 100644
--- a/packages/Shell/res/values-in/strings.xml
+++ b/packages/Shell/res/values-in/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kerangka"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Laporan bug sedang dibuat"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan bug tercatat"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Laporan bug <xliff:g id="ID">#%d</xliff:g> sedang dibuat"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Laporan bug <xliff:g id="ID">#%d</xliff:g> dijepret"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Menambahkan detail ke laporan bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Harap tunggu..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Gesek ke kiri untuk membagikan laporan bug Anda"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Sentuh untuk membagikan laporan bug Anda"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketuk untuk membagikan laporan bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan bug berisi data dari berbagai file log sistem, termasuk informasi pribadi dan rahasia. Hanya bagikan laporan bug dengan aplikasi dan orang yang Anda percaya."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tampilkan pesan ini lain kali"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan bug"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"tanpa nama"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detail"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Tangkapan layar"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan layar berhasil diambil."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Tangkapan layar berhasil diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan layar tidak dapat diambil."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detail laporan bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detail laporan bug <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nama file"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Judul"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Deskripsi detail"</string>
diff --git a/packages/Shell/res/values-is-rIS/strings.xml b/packages/Shell/res/values-is-rIS/strings.xml
index d175b4f..0d43719 100644
--- a/packages/Shell/res/values-is-rIS/strings.xml
+++ b/packages/Shell/res/values-is-rIS/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Skipanalína"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Verið er að búa til villutilkynningu"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Villutilkynning útbúin"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Verið er að búa til villutilkynningu <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Villutilkynning <xliff:g id="ID">#%d</xliff:g> búin til"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Bætir upplýsingum við villutilkynningu"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Augnablik..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Strjúktu til vinstri til að deila villuskýrslunni"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Snertu til að deila villutilkynningunni"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ýttu til að deila villutilkynningunni"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Villutilkynningar innihalda gögn úr hinum ýmsu annálsskrám kerfisins, þ. á m. persónuleg gögn og trúnaðarupplýsingar. Deildu villutilkynningum eingöngu með forritum og fólki sem þú treystir."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Sýna þessi skilaboð næst"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Villutilkynningar"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"án heitis"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Nánar"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjámynd"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tókst að taka skjámynd."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skjámynd tekin."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekki tókst að taka skjámynd."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Upplýsingar um villutilkynningu"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Upplýsingar villutilkynningar <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Skráarheiti"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titill"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ítarleg lýsing"</string>
diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml
index a954b0c..fc9383a 100644
--- a/packages/Shell/res/values-it/strings.xml
+++ b/packages/Shell/res/values-it/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Generazione segnalazione di bug in corso"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Segnalazione di bug acquisita"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generazione segnalazione di bug <xliff:g id="ID">#%d</xliff:g> in corso"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Segnalazione di bug <xliff:g id="ID">#%d</xliff:g> acquisita"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Aggiunta di dettagli alla segnalazione di bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Attendi..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Scorri verso sinistra per condividere il rapporto sui bug"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tocca per condividere la segnalazione di bug"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tocca per condividere la segnalazione di bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Le segnalazioni di bug contengono dati da vari file di log del sistema, incluse informazioni personali e private. Condividi le segnalazioni di bug solo con app e persone attendibili."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra questo messaggio la prossima volta"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapporti sui bug"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"senza nome"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Dettagli"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot acquisito."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot acquisito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Impossibile acquisire lo screenshot."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Dettagli della segnalazione di bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Dettagli sulla segnalazione di bug <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nome file"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titolo"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrizione dettagliata"</string>
diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index 40bd73b..335a2e8 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"מעטפת"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"מופק דוח על באג"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"דוח הבאגים צולם"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"יצירת הדוח על הבאג <xliff:g id="ID">#%d</xliff:g> מתבצעת"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"הדוח על הבאג <xliff:g id="ID">#%d</xliff:g> צולם"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"מוסיף פרטים לדוח על הבאג"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"המתן…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"החלק שמאלה כדי לשתף את דוח הבאגים"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"גע כדי לשתף את דוח הבאגים שלך"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"הקש כדי לשתף את הדוח על הבאג"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"דוחות על באגים כוללים נתונים מקובצי היומן השונים במערכת, כולל מידע אישי ופרטי. שתף דוחות באגים רק עם אפליקציות ואנשים שאתה סומך עליהם."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"הצג את ההודעה הזו בפעם הבאה"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"דוחות באגים"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ללא שם"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"פרטים"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"צילום מסך"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"צילום המסך בוצע בהצלחה."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"צילום המסך בוצע בהצלחה."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"לא ניתן היה לצלם מסך."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"פרטי דוח על באג"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"פרטי הדוח על הבאג <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"שם קובץ"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"כותרת"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"תיאור מפורט"</string>
diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml
index f0183b5..b98b05f 100644
--- a/packages/Shell/res/values-ja/strings.xml
+++ b/packages/Shell/res/values-ja/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"シェル"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"バグレポートを生成しています"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"バグレポートが記録されました"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"バグレポート <xliff:g id="ID">#%d</xliff:g> の生成中"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"バグレポート <xliff:g id="ID">#%d</xliff:g> の記録完了"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"バグレポートに詳細情報を追加しています"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"お待ちください…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"バグレポートを共有するには左にスワイプ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"バグレポートを共有するにはタップします"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"バグレポートを共有するにはタップします"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"バグレポートには、個人の非公開情報など、システムのさまざまなログファイルのデータが含まれます。共有する場合は信頼するアプリとユーザーのみを選択してください。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"このメッセージを次回も表示する"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"バグレポート"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"名前なし"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"詳細"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"スクリーンショット"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"スクリーンショットを撮影しました。"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"スクリーンショットを正常に撮影しました。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"スクリーンショットを撮影できませんでした。"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"バグレポートの詳細"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"バグレポート <xliff:g id="ID">#%d</xliff:g> の詳細"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ファイル名"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"タイトル"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細説明"</string>
diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml
index a7ad694..24d83a4 100644
--- a/packages/Shell/res/values-ka-rGE/strings.xml
+++ b/packages/Shell/res/values-ka-rGE/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"გარეკანი"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის გენერირება"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ანგარიში ხარვეზების შესახებ შექმნილია"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> გენერირდება"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> აღბეჭდილია"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ხარვეზის შესახებ ანგარიშს დეტალები ემატება"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"გთხოვთ, მოითმინოთ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"გაასრიალეთ მარცხნივ თქვენი ხარვეზის შეტყობინების გასაზიარებლად"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"შეეხეთ თქვენი ხარვეზების ანგარიშის გასაზიარებლად"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"შეეხეთ ხარვეზების შესახებ ანგარიშის გასაზიარებლად"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"შეცდომების ანგარიშები"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"უსახელო"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"დეტალები"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ეკრანის ანაბეჭდი"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ეკრანის ანაბეჭდი გადაღებულია წარმატებით."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ეკრანის ანაბეჭდი გადაღებულია წარმატებით."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ეკრანის ანაბეჭდის გადაღება ვერ მოხერხდა."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ხარვეზის შესახებ ანგარიშის დეტალები"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g>-ის დეტალები"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ფაილის სახელი"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"სათაური"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"დეტალური აღწერა"</string>
diff --git a/packages/Shell/res/values-kk-rKZ/strings.xml b/packages/Shell/res/values-kk-rKZ/strings.xml
index 25a3879..5878b17 100644
--- a/packages/Shell/res/values-kk-rKZ/strings.xml
+++ b/packages/Shell/res/values-kk-rKZ/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Қабыршық"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Қате туралы есеп жасалып жатыр"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Вирус туралы баянат қабылданды"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жасалуда"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жазып алынды"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Қате туралы есепке мәліметтер қосылуда"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күте тұрыңыз…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Қате туралы есепті бөлісу үшін солға жанаңыз"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Бөліс үшін, вирус туралы баянатты түртіңіз."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Қате туралы есепті бөлісу үшін түртіңіз"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Вирус туралы баянатта жүйеде тіркелген әртүрлі файлдар туралы деректер болады, оған жеке және құпия ақпарат та кіреді. Вирус баянаттарын сенімді қолданбалар және сенімді адамдармен ғана бөлісіңіз."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бұл хабарды келесі жолы көрсетіңіз"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Қате туралы баяндамалар"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"атаусыз"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Мәліметтер"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Скриншот"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот сәтті түсірілді."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Скриншот сәтті түсірілді."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот түсіру мүмкін болмады."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Қате туралы есептің мәліметтері"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі туралы мәліметтер"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Файл атауы"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Атауы"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Егжей-тегжейлі сипаттама"</string>
diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml
index 844c317..9c95e98 100644
--- a/packages/Shell/res/values-km-rKH/strings.xml
+++ b/packages/Shell/res/values-km-rKH/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"សែល"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"របាយការណ៍កំហុសកំពុងត្រូវបានបង្កើត"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"បាន​ចាប់​យក​របាយការណ៍​កំហុស"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសកំពុងត្រូវបានបង្កើត"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសត្រូវបានថត"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"កំពុងបន្ថែមព័ត៌មានលម្អិតទៅរបាយការណ៍កំហុស"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"សូម​រង់ចាំ…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"អូស​ទៅ​ឆ្វេង​​ ដើម្បី​ចែក​រំលែក​របាយការណ៍​កំហុស​របស់​អ្នក"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"ប៉ះ​ ដើម្បី​ចែក​រំលែក​របាយការណ៍​កំហុស​របស់​អ្នក"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នក"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"របាយការណ៍​កំហុស​រួមមាន​ឯកសារ​កំណត់​ហេតុ​ផ្សេងៗ​របស់​ប្រព័ន្ធ រួមមាន​ព័ត៌មាន​ផ្ទាល់ខ្លួន និង​ឯកជន។ ចែករំលែក​របាយការណ៍​កំហុស​ជា​មួយ​កម្មវិធី និង​មនុស្ស​ដែល​អ្នក​ទុក​ចិត្ត។"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"បង្ហាញ​សារ​នេះ​ពេល​ក្រោយ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"រាយការណ៍ពីកំហុស"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"គ្មានឈ្មោះ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ព័ត៌មានលម្អិត"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"រូបថតអេក្រង់"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"បានថតរូបថតអេក្រង់ដោយជោគជ័យ"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"រូបថតអេក្រង់ត្រូវបានថតដោយជោគជ័យ"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"មិនអាចថតរូបថតអេក្រង់បានទេ"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ព័ត៌មានលម្អិតពីរបាយការណ៍កំហុស"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ព័ត៌មានលម្អិតពី <xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុស"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ឈ្មោះ​ឯកសារ"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ចំណងជើង"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ការពិពណ៌នាលម្អិត"</string>
diff --git a/packages/Shell/res/values-kn-rIN/strings.xml b/packages/Shell/res/values-kn-rIN/strings.xml
index a3c9b95..ce6f3c0 100644
--- a/packages/Shell/res/values-kn-rIN/strings.xml
+++ b/packages/Shell/res/values-kn-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ಶೆಲ್"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ದೋಷ ವರದಿಯನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ದೋಷದ ವರದಿಯನ್ನು ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ದೋಷ ವರದಿಯ <xliff:g id="ID">#%d</xliff:g> ಅನ್ನು ರಚಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ದೋಷ ವರದಿಯ <xliff:g id="ID">#%d</xliff:g> ಅನ್ನು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿಕೊಳ್ಳಲಾಗಿದೆ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ಬಗ್ ವರದಿಗೆ ವಿವರಗಳನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ದಯವಿಟ್ಟು ನಿರೀಕ್ಷಿಸಿ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"ನಿಮ್ಮ ದೋಷ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಎಡಕ್ಕೆ ಸ್ವೈಪ್‌ ಮಾಡಿ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"ನಿಮ್ಮ ದೋಷದ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ನಿಮ್ಮ ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ವೈಯಕ್ತಿಕ ಮತ್ತು ಖಾಸಗಿ ಮಾಹಿತಿಯು ಸೇರಿದಂತೆ, ಸಿಸ್ಟಂನ ಹಲವಾರು ಲಾಗ್ ಫೈಲ್‌ಗಳಿಂದ ಡೇಟಾವನ್ನು ದೋಷದ ವರದಿಗಳು ಒಳಗೊಂಡಿವೆ. ನೀವು ನಂಬುವಂತಹ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಜನರೊಂದಿಗೆ ಮಾತ್ರ ದೋಷದ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ಈ ಸಂದೇಶವನ್ನು ಮುಂದಿನ ಬಾರಿ ತೋರಿಸಿ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ದೋಷ ವರದಿಗಳು"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ಹೆಸರಿಸದಿರುವುದು"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ವಿವರಗಳು"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಯಶಸ್ವಿಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಯಶಸ್ವಿಯಾಗಿ ತೆಗೆದುಕೊಳ್ಳಲಾಗಿದೆ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ತೆಗೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ಬಗ್ ವರದಿ ವಿವರಗಳು"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ದೋಷ ವರದಿಯ <xliff:g id="ID">#%d</xliff:g> ವಿವರಗಳು"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ಫೈಲ್‌ಹೆಸರು"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ಶೀರ್ಷಿಕೆ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ವಿವರವಾದ ವಿವರಣೆ"</string>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 912d940..70df8e2 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"셸"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"버그 신고 생성 중"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"버그 신고서 캡처됨"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 생성 중"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 캡처됨"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"세부정보를 버그 보고서에 추가"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"잠시 기다려 주세요..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"왼쪽으로 스와이프하여 버그 신고서를 공유하세요."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"버그 신고서를 공유하려면 터치하세요."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"버그 신고를 공유하려면 탭하세요."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"버그 신고서는 시스템의 다양한 로그 파일 데이터(예: 개인 및 비공개 정보)를 포함합니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"다음에 이 메시지 표시"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"버그 신고"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"이름 없음"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"세부정보"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"스크린샷"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"스크린샷을 찍었습니다."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"스크린샷을 찍었습니다."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"스크린샷을 찍을 수 없습니다."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"버그 신고 세부정보"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 세부정보"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"파일 이름"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"제목"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"자세한 설명"</string>
diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml
index 8ad785c..49d8d8d 100644
--- a/packages/Shell/res/values-ky-rKG/strings.xml
+++ b/packages/Shell/res/values-ky-rKG/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Командалык кабык"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Мүчүлүштүктөр тууралуу билдирүү түзүлүүдө"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Ката тууралуу билдирүү түзүлдү"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> түзүлүүдө"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Мүчүлүштүк жөнүндө кабардын чоо-жайы кошулууда"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күтө туруңуз…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ката жөнүндө кабар менен бөлүшүү үчүн солго серпип коюңуз"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Ката тууралуу билдирүүңүздү жөнөтүш үчүн, тийиңиз"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Мүчүлүштүк тууралуу билдирүүңүздү бөлүшүү үчүн таптап коюңуз"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Ката тууралуу билдирүүлөр системанын ар кандай лог файлдарынын берилиштерин камтыйт, аларга өздүк жана купуя маалыматтар дагы кирет. Ката тууралуу билдирүүлөрдү сиз ишенген колдонмолор жана адамдар менен гана бөлүшүңүз."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бул билдирүү кийин көрсөтүлсүн"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоолор"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"аталышы жок"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Чоо-жайы"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Скриншот"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот ийгиликтүү тартылды."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Скриншот ийгиликтүү тартылды."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Скриншот тартылбай койду."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Мүчүлүштүктөр жөнүндө кабардын чоо-жайы"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Мүчүлүштүк тууралуу билдирүүнүн <xliff:g id="ID">#%d</xliff:g> чоо-жайы"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Файлдын аталышы"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Аталышы"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Кененирээк маалымат"</string>
diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml
index d159254..61b06c8 100644
--- a/packages/Shell/res/values-lo-rLA/strings.xml
+++ b/packages/Shell/res/values-lo-rLA/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ກຳລັງສ້າງລາຍງານບັນຫາ"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ລາຍງານຈຸດບົກພ່ອງຖືກເກັບກຳແລ້ວ"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ກຳລັງສ້າງລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ບັນທຶກລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g> ແລ້ວ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ກຳລັງເພີ່ມລາຍລະອຽດໃສ່ລາຍງານຂໍ້ຜິດພາດ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ກະລຸນາລໍຖ້າ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"​ປັດ​ໄປ​ຊ້າຍ​ເພື່ອ​ສົ່ງ​ລາຍ​ງານ​ຂໍ້​ຜິດ​ພາດ​ຂອງ​ທ່ານ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"ແຕະເພື່ອສົ່ງການລາຍງານປັນຫາຂອງທ່ານ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ສະແດງຂໍ້ຄວາມນີ້ອີກໃນເທື່ອຕໍ່ໄປ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ລາຍ​ງານ​ບັນ​ຫາ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ບໍ່ມີຊື່"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ລາຍລະອຽດ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ພາບໜ້າຈໍ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ຖ່າຍພາບໜ້າຈໍສຳເລັດແລ້ວ."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ຖ່າຍພາບໜ້າຈໍສຳເລັດແລ້ວ."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ບໍ່ສາມາດຖ່າຍພາບໜ້າຈໍໄດ້."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ລາຍ​ລະ​ອຽດ​ການລາຍງານບັນຫາ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ລາຍລະອຽດຂອງລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ຊື່ໄຟລ໌"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ຊື່"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ຄຳອະທິບາຍແບບລະອຽດ"</string>
diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml
index 0c069c6..3418213 100644
--- a/packages/Shell/res/values-lt/strings.xml
+++ b/packages/Shell/res/values-lt/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Apvalkalas"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Pranešimas apie riktą generuojamas"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Riktų ataskaita užfiksuota"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) generuojamas"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) užfiksuotas"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Pridedama informacijos prie pranešimo apie riktą"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Palaukite…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Perbraukite kairėn, kad bendrintumėte rikto ataskaitą"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Palieskite, kad bendrintumėte riktų ataskaitą"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Palieskite, kad bendrintumėte pranešimą apie riktą"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Riktų ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Riktų ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rodyti šį pranešimą kitą kartą"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Riktų ataskaitos"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"be pavadinimo"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Informacija"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Ekrano kopija"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrano kopija sėkmingai padaryta."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Ekrano kopija sėkmingai sukurta."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nepavyko padaryti ekrano kopijos."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Išsami pranešimo apie riktą informacija"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Išsami informacija apie pranešimą apie riktą (<xliff:g id="ID">#%d</xliff:g>)"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Failo pavadinimas"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Pavadinimas"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Išsamus aprašas"</string>
diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml
index 1baa343..6108716 100644
--- a/packages/Shell/res/values-lv/strings.xml
+++ b/packages/Shell/res/values-lv/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Aizsargs"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Notiek kļūdas pārskata izveide"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Izveidots kļūdu pārskats"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> tiek ģenerēts"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> reģistrēts"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Informācijas pievienošana kļūdas pārskatam"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lūdzu, uzgaidiet..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Velciet pa kreisi, lai kopīgotu savu kļūdu ziņojumu."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Pieskarieties, lai kopīgotu kļūdu pārskatu."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Pieskarieties, lai kopīgotu kļūdas pārskatu."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Kļūdu pārskatā ir iekļauti dati no dažādiem sistēmas žurnālfailiem, tostarp personas dati un privāta informācija. Kļūdu pārskatus ieteicams kopīgot tikai ar uzticamām lietotnēm un lietotājiem."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rādīt šo ziņojumu nākamajā reizē"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Kļūdu ziņojumi"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"bez nosaukuma"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalizēta informācija"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Ekrānuzņēmums"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekrānuzņēmums ir veikts sekmīgi."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Ekrānuzņēmums ir veikts sekmīgi."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nevarēja veikt ekrānuzņēmumu."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Kļūdas pārskata informācija"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g>: detalizēta informācija"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Faila nosaukums"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Nosaukums"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detalizēts apraksts"</string>
diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml
index efbec8e..500196d 100644
--- a/packages/Shell/res/values-mk-rMK/strings.xml
+++ b/packages/Shell/res/values-mk-rMK/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Обвивка"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Се генерира извештајот за грешки"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Извештајот за грешка е снимен"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Се генерира извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештајот за грешки <xliff:g id="ID">#%d</xliff:g> е снимен"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Се додаваат детали на извештајот за грешка"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Почекајте..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Повлечете налево за да споделите пријава за грешка"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Допри да се сподели твојот извештај за грешка"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Допрете за да го споделите извештајот за грешки"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи лични и приватни информации. Извештаите за грешка споделувајте ги само со апликации и луѓе на коишто им верувате."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ја поракава следниот пат"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаи за грешки"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"неименувани"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Детали"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Слика од екранот"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Успешно е направена слика од екранот."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Успешно е направена слика од екранот."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не може да се направи слика од екранот."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали на извештајот за грешка"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Детали за извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Име на датотека"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Наслов"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детален опис"</string>
diff --git a/packages/Shell/res/values-ml-rIN/strings.xml b/packages/Shell/res/values-ml-rIN/strings.xml
index 82cfd6d..696aab2 100644
--- a/packages/Shell/res/values-ml-rIN/strings.xml
+++ b/packages/Shell/res/values-ml-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ഷെൽ"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ബഗ് റിപ്പോർട്ട് സൃഷ്ടിച്ചുകൊണ്ടിരിക്കുന്നു"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ബഗ് റിപ്പോർട്ട് ക്യാപ്‌ചർ ചെയ്‌തു"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> സൃഷ്ടിക്കുന്നു"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ബഗ് റിപ്പോർട്ടിലേക്ക് വിശദാംശങ്ങൾ ചേർക്കുന്നു"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"കാത്തിരിക്കുക..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നതിന് ഇടത്തേയ്‌ക്ക് സ്വൈപ്പുചെയ്യുക"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ സ്‌പർശിക്കുക"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"വ്യക്തിഗതവും സ്വകാര്യവുമായ വിവരങ്ങൾ ഉൾപ്പെടെ, സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള ഡാറ്റ, ബഗ് റിപ്പോർട്ടുകളിൽ അടങ്ങിയിരിക്കുന്നു. നിങ്ങൾ വിശ്വസിക്കുന്ന അപ്ലിക്കേഷനുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ഈ സന്ദേശം അടുത്ത തവണ ദൃശ്യമാക്കുക"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ബഗ് റിപ്പോർട്ടുകൾ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"പേരില്ലാത്തവർ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"വിശദാംശങ്ങൾ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"സ്‌ക്രീൻഷോട്ട്"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ബഗ് റിപ്പോർട്ട് വിശദാംശങ്ങൾ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> വിശദാംശങ്ങൾ"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ഫയല്‍നാമം"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"പേര്"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"വിശദമായ വിവരണം"</string>
diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml
index 856803d..62d83cb 100644
--- a/packages/Shell/res/values-mn-rMN/strings.xml
+++ b/packages/Shell/res/values-mn-rMN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Шел"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Алдааны тайланг үүсгэсэн"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Алдааны мэдээлэл хүлээн авав"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g> үүсгэгдэж байна"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g>-г бүртгэгдлээ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Алдааны тайланд дэлгэрэнгүй мэдээлэл нэмж байна"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Түр хүлээнэ үү..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Өөрийн согог репортыг хуваалцахын тулд зүүн шудрана уу"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Та алдааны мэдэгдлийг хуваалцах бол хүрнэ үү"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Програмд гарсан алдааны мэдээллээ хуваалцах бол дарна уу"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Гэмтлийн тухай тайлан"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"нэр байхгүй"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Дэлгэрэнгүй"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Дэлгэцийн зураг"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Дэлгэцийн зургийг амжилттай авлаа."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Дэлгэцийн зургийг амжилттай авлаа."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Дэлгэцийн зураг авах боломжгүй."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Алдааны дэлгэрэнгүй тайлан"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g>-ны дэлгэрэнгүй"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Файлын нэр"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Гарчиг"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Дэлгэрэнгүй тайлбар"</string>
diff --git a/packages/Shell/res/values-mr-rIN/strings.xml b/packages/Shell/res/values-mr-rIN/strings.xml
index 763eec6..e6b2b04 100644
--- a/packages/Shell/res/values-mr-rIN/strings.xml
+++ b/packages/Shell/res/values-mr-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"शेल"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"दोष अहवाल तयार केला जात आहे"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"दोष अहवाल कॅप्‍चर केला"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> तयार केला जात आहे"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> कॅप्चर केला"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"दोष अहवालामध्‍ये तपशील जोडत आहे"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा करा..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"आपला दोष अहवाल सामायिक करण्यासाठी डावीकडे स्वाइप करा"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"आपला दोष अहवाल सामायिक करण्‍यासाठी स्‍पर्श करा"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"आपला दोष अहवाल सामायिक करण्यासाठी टॅप करा"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"दोष अहवालांमध्‍ये वैयक्तिक आणि खाजगी माहितीसह, सिस्‍टमच्‍या अनेक लॉग फायलींमधील डेटा असतो. केवळ आपला विश्वास असलेल्‍या अ‍ॅप्‍स आणि लोकांसह दोष अहवाल सामायिक करा."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"पुढील वेळी हा संदेश दर्शवा"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"दोष अहवाल"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"अनामित"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"तपशील"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रीनशॉट"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रीनशॉट यशस्वीपणे घेतला."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रीनशॉट यशस्वीरित्या घेतला."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रीनशॉट घेणे शक्य झाले नाही."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"दोष अहवाल तपशील"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"दोष अहवाल <xliff:g id="ID">#%d</xliff:g> तपशील"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"फाईलनाव"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"तपशीलवार वर्णन"</string>
diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
index 1afe430..1d04253 100644
--- a/packages/Shell/res/values-ms-rMY/strings.xml
+++ b/packages/Shell/res/values-ms-rMY/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Laporan pepijat sedang dijana"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Laporan pepijat telah ditangkap"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> sedang dijana"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> telah ditangkap"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Menambahkan butiran pada laporan pepijat"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sila tunggu…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Leret ke kiri untuk berkongsi laporan pepijat anda"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Sentuh untuk berkongsi laporan pepijat anda"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketik untuk berkongsi laporan pepijat anda"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan pepijat mengandungi data dari pelbagai fail log sistem, termasuk maklumat peribadi dan sulit. Kongsikan laporan pepijat hanya dengan apl dan orang yang anda percayai."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan pepijat"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"tidak bernama"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Butiran"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Tangkapan skrin"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Tangkapan skrin berjaya diambil."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Tangkapan skrin berjaya diambil."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Tangkapan skrin tidak dapat diambil."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Butiran laporan pepijat"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Butiran laporan pepijat <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nama fail"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Tajuk"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Perihalan terperinci"</string>
diff --git a/packages/Shell/res/values-my-rMM/strings.xml b/packages/Shell/res/values-my-rMM/strings.xml
index e941111..f63c8c5 100644
--- a/packages/Shell/res/values-my-rMM/strings.xml
+++ b/packages/Shell/res/values-my-rMM/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"အခွံ"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ချွတ်ယွင်းမှု အစီရင်ခံစာကို ထုတ်ပေးနေသည်"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"အမှားအယွင်းမှတ်တမ်းကို အောင်မြင်စွာ သိမ်းဆည်းပြီး"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုထုတ်နေပါသည်"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုရယူထားပြီးပါပြီ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ချွတ်ယွင်းချက်အစီရင်ခံချက်သို့ အသေးစိတ်များပေါင်းထည့်ရန်"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ခေတ္တစောင့်ပါ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"သင်၏ ဘာဂ် အစီရင်ခံစာကို မျှပေးရန် ဘယ်ဘက်သို့ ပွတ်ဆွဲရန်"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"အမှားအယွင်း မှတ်တမ်းကို မျှဝေရန် ထိလိုက်ပါ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"သင့်ချွတ်ယွင်းမှုအစီရင်ခံချက်ကို မျှဝေရန် တို့ပါ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"အမှားအယွင်း မှတ်တမ်းမှာ ပါရှိသော အချက်အလက်များမှာ ကိုယ်ရေးကိုယ်တာ နဲ့ လုံခြုံရေး အချက်အလက်များပါဝင်သော စနစ်မှ ပြုလုပ်မှု မှတ်တမ်းများ ဖြစ်ပါသည်၊ အမှားအယွင်း မှတ်တမ်းများကို ယုံကြည်ရသော အပလီကေးရှင်းများနဲ့ လူများကိုသာ ပေးဝေပြသမှု လုပ်ပါရန်။"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ဤစာတန်းကို နောက်တစ်ခါတွင် ပြရန်"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ချို့ယွင်းမှု အစီရင်ခံစာများ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"အမည်မဲ့"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"အသေးစိတ်များ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံကို အောင်မြင်စွာ ရိုက်ပြီးပြီ။"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ဖန်သားပြင်ဓာတ်ပုံ အောင်မြင်စွာရိုက်ပြီးပါပြီ။"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"မျက်နှာပြင် လျှပ်တစ်ပြက်ပုံ မရိုက်နိုင်ပါ"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ချွတ်ယွင်းချက်အစီရင်ခံစာ အသေးစိတ်များ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> အသေးစိတ်များ"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ဖိုင်အမည်"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ခေါင်းစဉ်"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"အသေးစိတ် ဖော်ပြချက်"</string>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index 87b3530..328e8ae 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kommandoliste"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Feilrapporten blir generert"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Feilrapporten er lagret"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Feilrapporten <xliff:g id="ID">#%d</xliff:g> blir generert"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Feilrapporten <xliff:g id="ID">#%d</xliff:g> er fullført"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Legger til detaljer i feilrapporten"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vent litt"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Sveip til venstre for å dele feilrapporten din"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Trykk for å dele feilrapporten din"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trykk for å dele feilrapporten"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Feilrapporter inkluderer data fra systemets forskjellige loggfiler. Dette omfatter personlig og privat informasjon. Du bør bare dele feilrapporter med apper og folk du stoler på."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne meldingen neste gang"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Feilrapporter"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"uten navn"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detaljer"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjermdump"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skjermdumpen er tatt."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skjermdumpen er tatt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skjermdumpen kunne ikke tas."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detaljer om feilrapporten"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detaljer om feilrapporten <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filnavn"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Tittel"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljert beskrivelse"</string>
diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml
index 5b68ece..62bfead 100644
--- a/packages/Shell/res/values-ne-rNP/strings.xml
+++ b/packages/Shell/res/values-ne-rNP/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"सेल"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"बग रिपोर्ट उत्पन्न भइरहेको छ"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"बग प्रतिवेदन समातियो"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g>लाई निकालिदैछ"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g>लाई कैद गरियो"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"बग रिपोर्टमा विवरणहरू थप्दै"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"कृपया प्रतीक्षा गर्नुहोला..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"तपाईँको बग रिपोर्ट साझेदारी गर्न बायाँ स्वाइप गर्नुहोस्"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"तपाईंको बग रिपोर्ट साझेदारी गर्न छुनुहोस्"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"तपाईंको बग रिपोर्टलाई साझेदारी गर्न ट्याप गर्नुहोस्"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"बग रिपोर्टहरूमा प्रणालीका विभिन्न लग फाइलहरूबाट व्यक्तिगत तथा नीजि सूचनासहितको डेटा रहन्छ।  बग रिपोर्टहरू अनुप्रयोगहरू र तपाईँले विश्वास गरेका व्यक्तिहरूसँग मात्र साझेदारी गर्नुहोस्।"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यो सन्देश अर्को पटक देखाउनुहोस्"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रिपोर्टहरू"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"(नामविहीन)"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"विवरण"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"स्क्रिनशट"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"स्क्रिनशट सफलतापूर्वक लिइयो।"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"स्क्रिनशट सफलतापूर्वक लिइयो।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"स्क्रिनशट लिन सकिएन।"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"बग रिपोर्टको विवरण"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"बग रिपोर्ट <xliff:g id="ID">#%d</xliff:g>का विवरणहरू"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"फाइलको नाम"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"शीर्षक"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"विस्तृत विवरण"</string>
diff --git a/packages/Shell/res/values-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml
index dd67ccd..2f4b215 100644
--- a/packages/Shell/res/values-nl/strings.xml
+++ b/packages/Shell/res/values-nl/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Bugrapport wordt gegenereerd"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Foutenrapport vastgelegd"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bugrapport <xliff:g id="ID">#%d</xliff:g> wordt gegenereerd"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Bugrapport <xliff:g id="ID">#%d</xliff:g> is vastgelegd"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Details toevoegen aan het bugrapport"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Even geduld…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veeg naar links om je bugmelding te delen"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Raak aan om je foutenrapport te delen"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tik om je bugrapport te delen"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Foutenrapporten bevatten gegevens uit de verschillende logbestanden van het systeem, waaronder persoonlijke en privégegevens. Deel foutenrapporten alleen met apps en mensen die u vertrouwt."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Dit bericht de volgende keer weergeven"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutenrapporten"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"naamloos"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Details"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Screenshot is gemaakt."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Screenshot is gemaakt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Screenshot kan niet worden gemaakt."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Details van bugrapport"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Details van bugrapport <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Bestandsnaam"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titel"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Gedetailleerde beschrijving"</string>
diff --git a/packages/Shell/res/values-pa-rIN/strings.xml b/packages/Shell/res/values-pa-rIN/strings.xml
index 96addbf..dc2277f 100644
--- a/packages/Shell/res/values-pa-rIN/strings.xml
+++ b/packages/Shell/res/values-pa-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ਸ਼ੈਲ"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"ਬੱਗ ਰਿਪੋਰਟ ਸਿਰਜੀ ਜਾ ਰਹੀ ਹੈ"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"ਬਗ ਰਿਪੋਰਟ ਕੈਪਚਰ ਕੀਤੀ"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਸਿਰਜੀ ਜਾ ਰਹੀ ਹੈ"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਕੈਪਚਰ ਕੀਤੀ ਗਈ"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"ਬੱਗ ਰਿਪੋਰਟ ਵਿੱਚ ਵੇਰਵਿਆਂ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"ਕਿਰਪਾ ਕਰਕੇ ਉਡੀਕ ਕਰੋ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"ਤੁਹਾਡੀ ਬਗ ਰਿਪੋਰਟ ਸ਼ੇਅਰ ਕਰਨ ਲਈ ਖੱਬੇ ਪਾਸੇ ਸਵਾਈਪ ਕਰੋ"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"ਆਪਣੀ ਬਗ ਰਿਪੋਰਟ ਸ਼ੇਅਰ ਕਰਨ ਲਈ ਛੋਹਵੋ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"ਬਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਸਿਸਟਮ ਦੀਆਂ ਭਿੰਨ ਲੌਗ ਫਾਈਲਾਂ ਦਾ ਡਾਟਾ ਹੁੰਦਾ ਹੈ, ਨਿੱਜੀ ਅਤੇ ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ ਸਮੇਤ। ਕੇਵਲ ਉਹਨਾਂ ਐਪਸ ਅਤੇ ਲੋਕਾਂ ਨਾਲ ਬਗ ਰਿਪੋਰਟਾਂ ਸ਼ੇਅਰ ਕਰੋ, ਜਿਹਨਾਂ ਤੇ ਤੁਸੀਂ ਭਰੋਸਾ ਕਰਦੇ ਹੋ।"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ਅਗਲੀ ਵਾਰ ਇਹ ਸੁਨੇਹਾ ਦਿਖਾਓ"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ਬਗ ਰਿਪੋਰਟਾਂ"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ਬਿਨਾਂ-ਨਾਮ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"ਵੇਰਵੇ"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਫਲਤਾਪੂਰਵਕ ਲਿਆ ਗਿਆ।"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਨਹੀਂ ਲਿਆ ਜਾ ਸਕਿਆ।"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"ਬੱਗ ਰਿਪੋਰਟ ਵੇਰਵੇ"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"ਬੱਗ ਰਿਪੋਰਟ <xliff:g id="ID">#%d</xliff:g> ਵੇਰਵੇ"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ਫ਼ਾਈਲ ਨਾਮ"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ਸਿਰਲੇਖ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"ਵਿਸਥਾਰ ਸਹਿਤ ਵਰਣਨ"</string>
diff --git a/packages/Shell/res/values-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml
index 7a67ac6..c585568 100644
--- a/packages/Shell/res/values-pl/strings.xml
+++ b/packages/Shell/res/values-pl/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Powłoka"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Trwa generowanie raportu o błędzie"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Raport o błędach został zapisany"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generuję raport o błędzie <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Raport o błędzie <xliff:g id="ID">#%d</xliff:g> został zapisany"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaję szczegóły do raportu o błędzie"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Czekaj..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Przesuń palcem w lewo, by udostępnić swoje zgłoszenie błędu"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Kliknij, by udostępnić raport o błędach"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Kliknij, by udostępnić raport o błędzie"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Raporty o błędach zawierają dane z różnych plików dzienników systemu, w tym dane osobowe i prywatne. Udostępniaj je tylko aplikacjom i osobom, którym ufasz."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaż ten komunikat następnym razem"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Raporty o błędach"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"bez nazwy"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Szczegóły"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Zrzut ekranu"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Zrobiono zrzut ekranu."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Zrzut ekranu został zrobiony."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Nie udało się zrobić zrzutu ekranu."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Szczegóły zgłoszenia błędu"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Szczegóły raportu o błędzie <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nazwa pliku"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Tytuł"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Szczegółowy opis"</string>
diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml
index 471e959..fc6e21c 100644
--- a/packages/Shell/res/values-pt-rBR/strings.xml
+++ b/packages/Shell/res/values-pt-rBR/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Um relatório do bug está sendo gerado"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de bugs capturado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para compartilhar seu relatório de bugs"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sem nome"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalhes"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Capturas de tela"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalhes do relatório de bugs <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nome do arquivo"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
index ed78f55..252edb1 100644
--- a/packages/Shell/res/values-pt-rPT/strings.xml
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"O relatório de erro está a ser criado"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de erros capturado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório de erro <xliff:g id="ID">#%d</xliff:g> está a ser criado"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório de erro <xliff:g id="ID">#%d</xliff:g> criado"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"A adicionar detalhes ao relatório de erro"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslizar rapidamente para a esquerda para partilhar o seu relatório de erros"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para partilhar o relatório de erros"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para partilhar o relatório de erro"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de erros incluem dados de vários ficheiros de registo do sistema, nomeadamente informações pessoais e privadas. Partilhe relatórios de erros apenas com aplicações e pessoas fidedignas."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de erros"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sem nome"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalhes"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captura de ecrã"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecrã tirada com êxito."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Captura de ecrã tirada com êxito."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível tirar a captura de ecrã."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório de erro"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalhes do relatório de erro <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nome do ficheiro"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml
index 471e959..fc6e21c 100644
--- a/packages/Shell/res/values-pt/strings.xml
+++ b/packages/Shell/res/values-pt/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Um relatório do bug está sendo gerado"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Relatório de bugs capturado"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Toque para compartilhar seu relatório de bugs"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sem nome"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalhes"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Capturas de tela"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de tela concluída."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Captura de tela concluída."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Não foi possível fazer a captura de tela."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalhes do relatório do bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detalhes do relatório de bugs <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Nome do arquivo"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Título"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descrição detalhada"</string>
diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml
index af67bc6..d720417 100644
--- a/packages/Shell/res/values-ro/strings.xml
+++ b/packages/Shell/res/values-ro/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Se generează raportul de eroare"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Raportul despre erori a fost creat"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> se generează"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> a fost creat"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Se adaugă detaliile la raportul de eroare"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Așteptați…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Glisați la stânga pentru a trimite raportul de erori"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Atingeți pentru a permite accesul la raportul despre erori"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Atingeți pentru a trimite raportul de eroare"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Rapoartele despre erori conțin date din diferite fișiere de jurnal ale sistemului, inclusiv informații private și personale. Permiteți accesul la rapoartele despre erori numai aplicațiilor și persoanelor în care aveți încredere."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afișați acest mesaj data viitoare"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapoarte de erori"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"fără nume"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detalii"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Captură de ecran"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Captura de ecran a fost făcută."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Captura de ecran a fost făcută."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Captura de ecran nu a putut fi făcută."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detalii privind raportul de eroare"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detaliile raportului de eroare <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Numele fișierului"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titlu"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Descriere detaliată"</string>
diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml
index a5e2bd2..ed5ecaf 100644
--- a/packages/Shell/res/values-ru/strings.xml
+++ b/packages/Shell/res/values-ru/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Оболочка"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Создание отчета об ошибке…"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Отчет об ошибке сохранен"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Создание отчета об ошибке <xliff:g id="ID">#%d</xliff:g>…"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Отчет об ошибке <xliff:g id="ID">#%d</xliff:g> сохранен"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Добавление данных в отчет об ошибке"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Подождите…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведите влево, чтобы отправить отчет"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Нажмите, чтобы отправить отчет об ошибках"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Нажмите, чтобы отправить отчет об ошибке."</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показать это сообщение в следующий раз"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчеты об ошибках"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"без названия"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Детали"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Скриншоты"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Скриншот готов"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Скриншот сделан"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не удалось сделать скриншот"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детали отчета об ошибке"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Данные отчета об ошибке <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Название файла"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Название"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Подробное описание"</string>
diff --git a/packages/Shell/res/values-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml
index 866c0f7..cd8fba3 100644
--- a/packages/Shell/res/values-si-rLK/strings.xml
+++ b/packages/Shell/res/values-si-rLK/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ෂෙල්"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"දෝෂ වාර්තාවක් ජනනය කරමින් පවතී"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"දෝෂ වාර්තාව ලබාගන්නා ලදි"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"දෝෂ වාර්තා <xliff:g id="ID">#%d</xliff:g> ජනනය කරමින් පවතී"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"දෝෂ වාර්තා <xliff:g id="ID">#%d</xliff:g> ග්‍රහණය කර ගන්නා ලදී"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"දෝෂ වාර්තාව වෙත විස්තර එක් කිරීම"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"කරුණාකර රැඳී සිටින්න..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"ඔබගේ දෝෂ වාර්තාව බෙදාගැනීමට වමට ස්වයිප් කරන්න"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"ඔබගේ දෝෂ වාර්තාව බෙදා ගැනීමට ස්පර්ශ කරන්න"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ඔබගේ දෝෂ වාර්තාව බෙදා ගැනීමට තට්ටු කරන්න"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"පුද්ගලික සහ පෞද්ගලික තොරතුරු ඇතුළත්ව පද්ධතියේ විවිධ ලොග් ගොනු වල දත්ත දෝෂ වාර්තාවේ අඩංගු වේ. ඔබට විශ්වාසවන්ත යෙදුම් සහ පුද්ගලයින් සමඟ පමණක් දෝෂ වාර්තා බෙදා ගන්න."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ඊළඟ වෙලාවේ මෙම පණිවිඩය පෙන්වන්න"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"දෝෂ වාර්තා"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"නම් නොකළ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"විස්තර"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"තිර රුව"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"සාර්ථකව තිර රුවක් ගන්නා ලදී."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"සාර්ථකව තිර රුවක් ගන්නා ලදී."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"තිර රුවක් ගත නොහැකි විය."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"දෝෂ වාර්තා විස්තර"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"දෝෂ වාර්තා <xliff:g id="ID">#%d</xliff:g> විස්තර"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ගොනුවේ නම"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"මාතෘකාව"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"සවිස්තර විස්තරය"</string>
diff --git a/packages/Shell/res/values-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml
index f207480..23e67f5 100644
--- a/packages/Shell/res/values-sk/strings.xml
+++ b/packages/Shell/res/values-sk/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Prostredie"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Generuje sa hlásenie chyby"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Hlásenie o chybách bolo vytvorené"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generuje sa hlásenie chyby <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Hlásenie chyby <xliff:g id="ID">#%d</xliff:g> bolo zaznamenané"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Pridanie podrobností o hlásení chyby"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Čakajte prosím…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ak chcete hlásenie o chybe zdieľať, prejdite prstom doľava."</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Hlásenie o chybách môžete zdielať klepnutím"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hlásenie chyby môžete zdieľať klepnutím"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Správy o chybách obsahujú údaje z rôznych súborov denníkov systému vrátane osobných a súkromných informácií. Zdieľajte ich iba s dôveryhodnými aplikáciami a ľuďmi."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobraziť túto správu nabudúce"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hlásenia chýb"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"bez názvu"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Podrobnosti"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Snímka obrazovky"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Snímka obrazovky bola zaznamenaná."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Snímka obrazovky bola úspešne zaznamenaná."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Snímku obrazovky sa nepodarilo zaznamenať."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti hlásenia chyby"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Podrobnosti hlásenia chyby <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Názov súboru"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Názov"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podrobný popis"</string>
diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml
index c249961..519f3f2 100644
--- a/packages/Shell/res/values-sl/strings.xml
+++ b/packages/Shell/res/values-sl/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Lupina"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Poročilo o napakah se pripravlja"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Poročilo o napaki je posneto"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> je v izdelavi"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> zajeto"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodajanje podrobnosti v poročilo o napakah"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Počakajte ..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Povlecite v levo, če želite poslati sporočilo o napaki"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Dotaknite se, če želite deliti sporočilo o napaki z drugimi"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dotaknite se, če želite poročilo o napaki dati v skupno rabo"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Poročila o napakah vsebujejo podatke iz različnih dnevniških datotek sistema, vključno z osebnimi in zasebnimi podatki. Poročila o napakah delite samo z aplikacijami in ljudmi, ki jim zaupate."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži to sporočilo naslednjič"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Poročila o napakah"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"neimenovano"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Podrobnosti"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Posnetek zaslona"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Posnetek zaslon je bil uspešno ustvarjen."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Posnetek zaslona je bil uspešno ustvarjen."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Posnetka zaslon ni bilo mogoče ustvariti."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Podrobnosti o poročilu o napakah"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Podrobnosti poročila o napaki <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Ime datoteke"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Naslov"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Podroben opis"</string>
diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml
index 8a306b3..5e3c706 100644
--- a/packages/Shell/res/values-sq-rAL/strings.xml
+++ b/packages/Shell/res/values-sq-rAL/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Guaska"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Po krijohet raporti i defekteve në kod"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Raporti i defektit në kod u regjistrua"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> po krijohet"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> u regjistrua"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Po shtohen detajet te raporti i defekteve në kod"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Qëndro në pritje..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Rrëshqit majtas për të ndarë raportin e defektit në kod"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Prek për të ndarë raportin e defektit në kod"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trokit për të ndarë raportin e defekteve në kod"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Raportet e gabimeve përmbajnë të dhëna nga skedarë të ndryshëm ditarësh sistemi, përfshi informacione personale dhe private. Shpërndaji publikisht raportet e gabimeve vetëm me aplikacionet dhe personat që iu beson."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tregoje këtë mesazh herën tjetër"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Raportet e gabimeve"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"e paemërtuar"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detajet"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Pamja e ekranit"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Pamja e ekranit u realizua me sukses."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Pamja e ekranit u regjistrua me sukses."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Pamja e ekranit nuk mund të realizohej."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Detajet e raportimit të gabimeve në kod"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detajet e raportit të defekteve në kod <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Emri i skedarit"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Titulli"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Përshkrimi i detajuar"</string>
diff --git a/packages/Shell/res/values-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml
index 9bff65c..55119b6 100644
--- a/packages/Shell/res/values-sr/strings.xml
+++ b/packages/Shell/res/values-sr/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Извештај о грешци се генерише"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Извештај о грешци је снимљен"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> се генерише"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештај о грешци <xliff:g id="ID">#%d</xliff:g> је снимљен"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Додају се детаљи у извештај о грешци"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Сачекајте..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Превуците улево да бисте делили извештај о грешкама"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Додирните да бисте делили извештај о грешци"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Додирните да бисте делили извештај о грешци"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Извештаји о грешкама садрже податке из различитих системских датотека евиденције, укључујући личне и приватне податке. Делите извештаје о грешкама само са апликацијама и људима у које имате поверења."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ову поруку следећи пут"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаји о грешкама"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"неименовано"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Детаљи"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Снимци екрана"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Снимање екрана је успело."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Снимак екрана је направљен."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Снимање екрана није успело."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Детаљи извештаја о грешци"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Детаљи извештаја о грешци <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Назив датотеке"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Наслов"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детаљни опис"</string>
diff --git a/packages/Shell/res/values-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml
index fb962bf..085f57e 100644
--- a/packages/Shell/res/values-sv/strings.xml
+++ b/packages/Shell/res/values-sv/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Skal"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Felrapporten genereras"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Felrapporten har skapats"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Felrapporten <xliff:g id="ID">#%d</xliff:g> genereras"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Felrapporten <xliff:g id="ID">#%d</xliff:g> har skapats"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Lägger till information i felrapporten"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vänta …"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Svep åt vänster om du vill dela felrapporten"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Tryck om du vill dela felrapporten"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tryck om du vill dela felrapporten"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Felrapporter innehåller data från systemets olika loggfiler, inklusive personliga och privata uppgifter. Dela bara felrapporter med personer du litar på."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Visa det här meddelandet nästa gång"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Felrapporter"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"namnlös"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Information"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skärmdump"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"En skärmdump har tagits."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skärmdump har tagits."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Det gick inte att ta skrämdump."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Information för felrapporten"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Information för felrapporten <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filnamn"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Namn"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detaljerad beskrivning"</string>
diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml
index de46414..c5a8ef1 100644
--- a/packages/Shell/res/values-sw/strings.xml
+++ b/packages/Shell/res/values-sw/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Ganda"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Inatayarisha ripoti ya hitilafu"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Ripoti ya hitilafu imenaswa"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g> inatayarishwa"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g> imerekodiwa"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Inaongeza maelezo kwenye ripoti ya hitilafu"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Tafadhali subiri…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Telezesha kidole kushoto ili ushiriki ripoti yako ya hitilafu"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Gusa ili ushiriki ripoti yako ya hitilafu"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Gonga ili ushiriki ripoti yako ya hitilafu"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Ripoti ya hitilafu ina data kutoka kwenye faili za kumbukumbu mbalimbali za mfumo, pamoja na maelezo ya kibinafsi na faragha. Shiriki ripoti ya hitilafu na programu na watu unaowaamini pekee."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Onyesha ujumbe huu wakati mwingine"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Ripoti za hitilafu"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"Isiyo na jina"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Maelezo"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Picha ya skrini"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Imepiga picha ya skrini."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Imepiga picha ya skrini."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Haikupiga picha ya skrini."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Maelezo kuhusu ripoti ya hitilafu"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Maelezo ya ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Jina la faili"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Kichwa"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Maelezo ya kina"</string>
diff --git a/packages/Shell/res/values-ta-rIN/strings.xml b/packages/Shell/res/values-ta-rIN/strings.xml
index 15c7014..7ef89e2 100644
--- a/packages/Shell/res/values-ta-rIN/strings.xml
+++ b/packages/Shell/res/values-ta-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"ஷெல்"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"பிழை அறிக்கை உருவாக்கப்படுகிறது"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"பிழை அறிக்கைகள் படமெடுக்கப்பட்டன"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> உருவாக்கப்படுகிறது"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> எடுக்கப்பட்டது"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"பிழை அறிக்கையில் விவரங்களைச் சேர்க்கிறது"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"காத்திருக்கவும்…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"பிழை அறிக்கையைப் பகிர இடது புறமாகத் தேய்க்கவும்"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"உங்கள் பிழை அறிக்கையைப் பகிர, தொடவும்"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"பிழை அறிக்கையைப் பகிர, தட்டவும்"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"பிழை அறிக்கைகளில், சொந்த வாழ்க்கை மற்றும் தனிப்பட்ட தகவல் உள்பட கணினியின் பல்வேறு பதிவுகளில் உள்ள தரவு இருக்கும். நீங்கள் நம்பும் பயன்பாடுகள் மற்றும் நபர்களுடன் மட்டும் பிழை அறிக்கைகளைப் பகிரவும்."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"இந்தச் செய்தியை அடுத்த முறைக் காட்டு"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"பிழை அறிக்கைகள்"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"பெயரிடப்படாதது"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"விவரங்கள்"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ஸ்கிரீன் ஷாட்"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ஸ்கிரீன் ஷாட்டை எடுக்க முடியவில்லை."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"பிழை அறிக்கை விவரங்கள்"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"பிழை அறிக்கை <xliff:g id="ID">#%d</xliff:g> இன் விவரங்கள்"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"கோப்புப்பெயர்"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"தலைப்பு"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"விரிவான விளக்கம்"</string>
diff --git a/packages/Shell/res/values-te-rIN/strings.xml b/packages/Shell/res/values-te-rIN/strings.xml
index c84ec9a..6ba816b 100644
--- a/packages/Shell/res/values-te-rIN/strings.xml
+++ b/packages/Shell/res/values-te-rIN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"షెల్"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"బగ్ నివేదిక ఉత్పాదించబడుతోంది"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"బగ్ నివేదిక క్యాప్చర్ చేయబడింది"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"బగ్ నివేదిక <xliff:g id="ID">#%d</xliff:g> ఉత్పాదించబడుతోంది"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"బగ్ నివేదిక <xliff:g id="ID">#%d</xliff:g> సంగ్రహించబడింది"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"బగ్ నివేదికకు వివరాలను జోడిస్తోంది"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"దయచేసి వేచి ఉండండి..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి ఎడమవైపుకు స్వైప్ చేయండి"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి తాకండి"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి నొక్కండి"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"బగ్ నివేదికలు వ్యక్తిగతమైన మరియు రహస్యమైన సమాచారంతో సహా సిస్టమ్ యొక్క విభిన్న లాగ్ ఫైల్‌ల్లోని డేటాను కలిగి ఉంటాయి. కనుక బగ్ నివేదికలను మీరు విశ్వసించే అనువర్తనాలు మరియు వ్యక్తులతో మాత్రమే భాగస్వామ్యం చేయండి."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"తదుపరిసారి ఈ సందేశాన్ని చూపు"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"బగ్ నివేదికలు"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"పేరు లేనివి"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"వివరాలు"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"స్క్రీన్‌షాట్"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"స్క్రీన్‌షాట్ విజయవంతంగా తీయబడింది."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"స్క్రీన్‌షాట్ విజయవంతంగా తీయబడింది."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"స్క్రీన్‌షాట్‌ను తీయడం సాధ్యపడలేదు."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"బగ్ నివేదిక వివరాలు"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"బగ్ నివేదిక <xliff:g id="ID">#%d</xliff:g> వివరాలు"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ఫైల్ పేరు"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"శీర్షిక"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"సమగ్ర వివరణ"</string>
diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml
index f29978e..d68ca26 100644
--- a/packages/Shell/res/values-th/strings.xml
+++ b/packages/Shell/res/values-th/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"กำลังสร้างรายงานข้อบกพร่อง"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"จับภาพรายงานข้อบกพร่องแล้ว"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"กำลังสร้างรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"บันทึกรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g> แล้ว"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"กำลังเพิ่มรายละเอียดในรายงานข้อบกพร่อง"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"โปรดรอสักครู่…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"กวาดไปทางซ้ายเพื่อแชร์รายงานข้อบกพร่อง"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"รายงานข้อบกพร่องมีข้อมูลจากไฟล์บันทึกต่างๆ ของระบบ รวมถึงข้อมูลส่วนตัว แชร์รายงานข้อบกพร่องกับแอปและบุคคลที่คุณไว้ใจเท่านั้น"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"แสดงข้อความนี้ในครั้งต่อไป"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"รายงานข้อบกพร่อง"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ไม่มีชื่อ"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"รายละเอียด"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"ภาพหน้าจอ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"จับภาพหน้าจอสำเร็จแล้ว"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"จับภาพหน้าจอสำเร็จแล้ว"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"ไม่สามารถจับภาพหน้าจอได้"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"รายละเอียดรายงานข้อบกพร่อง"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"รายละเอียดรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"ชื่อไฟล์"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"ชื่อ"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"คำอธิบายโดยละเอียด"</string>
diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml
index c12191a..432eb90 100644
--- a/packages/Shell/res/values-tl/strings.xml
+++ b/packages/Shell/res/values-tl/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Binubuo na ang ulat ng bug"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Na-capture ang ulat ng bug"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Binubuo na ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Na-capture ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Pagdaragdag ng mga detalye sa ulat ng bug"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Mangyaring maghintay..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Mag-swipe pakaliwa upang ibahagi ang iyong ulat ng bug"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Pindutin upang ibahagi ang iyong ulat ng bug"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Mag-tap upang ibahagi ang iyong ulat ng bug"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Naglalaman ang mga ulat ng bug ng data mula sa iba\'t ibang file ng log ng system, kabilang ang personal at pribadong impormasyon. Magbahagi lang ng mga ulat ng bug sa apps at mga tao na pinagkakatiwalaan mo."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Mga ulat sa bug"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"walang pangalan"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Mga Detalye"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Screenshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Nakunan ng screenshot."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Matagumpay na nakakuha ng screenshot."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Hindi makunan ng screenshot."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Mga detalye ng ulat ng bug"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Mga detalye ng ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Filename"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Pamagat"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Detalyadong paglalarawan"</string>
diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml
index 3f562d7..dae377f 100644
--- a/packages/Shell/res/values-tr/strings.xml
+++ b/packages/Shell/res/values-tr/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Kabuk"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Hata raporu oluşturuluyor"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Hata raporu kaydedildi"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) oluşturuluyor"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) yakalandı"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Hata raporuna ayrıntılar ekleniyor"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfen bekleyin…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Hata raporunuzu paylaşmak için hızlıca sola kaydırın"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Hata raporunuzu paylaşmak için dokunun"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hata raporunuzu paylaşmak için hafifçe dokunun"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Hata raporları, kişisel ve özel bilgiler dahil olmak üzere sistemin çeşitli günlük dosyalarından veriler içerir. Hata raporlarını sadece güvendiğiniz uygulamalar ve kişilerle paylaşın."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu iletiyi göster"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hata raporları"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"adsız"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Ayrıntılar"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Ekran görüntüsü"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Ekran görüntüsü başarıyla alındı."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Ekran görüntüsü başarıyla alındı."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Ekran görüntüsü alınamadı."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Hata raporu ayrıntıları"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) ayrıntıları"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Dosya adı"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Başlık"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Ayrıntılı açıklama"</string>
diff --git a/packages/Shell/res/values-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml
index 93e6511..02eeb2f 100644
--- a/packages/Shell/res/values-uk/strings.xml
+++ b/packages/Shell/res/values-uk/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Оболонка"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Генерується повідомлення про помилку"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Звіт про помилки створено"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Генерується повідомлення про помилку <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Повідомлення про помилку <xliff:g id="ID">#%d</xliff:g> створено"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Додаються деталі до повідомлення про помилку"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Зачекайте…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведіть пальцем ліворуч, щоб надіслати звіт про помилки"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Торкніться, щоб надіслати звіт про помилки"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Торкніться, щоб надіслати повідомлення про помилку"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Звіти про помилки містять дані з різних файлів журналу системи, зокрема особисті та конфіденційні. Надсилайте звіт про помилки лише тим, кому довіряєте."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показати це повідомлення наступного разу"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Звіти про помилки"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"без назви"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Деталі"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Знімок екрана"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Знімок екрана зроблено."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Знімок екрана зроблено."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Не вдалося зробити знімок екрана."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Деталі повідомлення про помилку"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Деталі повідомлення про помилку <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Назва файлу"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Назва"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Детальний опис"</string>
diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml
index 52a45a0..23cada6 100644
--- a/packages/Shell/res/values-ur-rPK/strings.xml
+++ b/packages/Shell/res/values-ur-rPK/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"شیل"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"بگ رپورٹ تخلیق ہو رہی ہے"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"بَگ رپورٹ کیپچر کر لی گئی"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> تخلیق ہو رہی ہے"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کیپچر ہو گئی"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"بگ رپورٹ میں تفصیلات شامل کی جا رہی ہیں"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"براہ کرم انتظار کریں…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے بائیں سوائپ کریں"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"اپنی بَگ رپورٹ کا اشتراک کرنے کیلئے ٹچ کریں"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"بَگ رپورٹس میں سسٹم کی مختلف لاگ فائلوں سے ڈیٹا شامل ہوتا ہے، بشمول ذاتی اور نجی معلومات۔ بَگ رپورٹس کا اشتراک صرف اپنے بھروسے مند ایپس اور لوگوں کے ساتھ کریں۔"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"یہ پیغام اگلی بار دکھائیں"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"بگ رپورٹس"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"بغیر نام"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"تفصیلات"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"اسکرین شاٹ"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"اسکرین شاٹ کامیابی سے لے لیا گیا۔"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"اسکرین شاٹ کامیابی سے لے لیا گیا۔"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"سکرین شاٹ نہیں لیا جا سکا۔"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"بگ رپورٹ کی تفصیلات"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کی تفصیلات"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"فائل کا نام"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"عنوان"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"تفصیلی وضاحت"</string>
diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml
index 56e0965..39703a2 100644
--- a/packages/Shell/res/values-uz-rUZ/strings.xml
+++ b/packages/Shell/res/values-uz-rUZ/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Terminal"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Xatoliklar hisoboti tayyorlanmoqda"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Xatolik hisobotini yozib olindi"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tayyorlanmoqda"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) yozib olindi"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Xatoliklar hisobotiga tafsilotlar qo‘shilmoqda"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Iltimos, kuting…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Xatolik hisobotini yuborish uchun barmog‘ingiz bilan chapga suring"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Xatolik hisobotini bo‘lishish uchun barmog‘ingizni tegizing."</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Xatoliklar hisobotini ulashish uchun bosing"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Xatolik hisobotlari tizimdagi har xil jurnal fayllardagi ma’lumotlarni, shuningdek, shaxsiy hamda maxfiy ma’lumotlarni o‘z ichiga oladi. Xatolik hisobotlarini faqat ishonchli dasturlar va odamlar bilan bo‘lishing."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ushbu xabar keyingi safar ko‘rsatilsin"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Xatoliklar hisoboti"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"nomsiz"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Tafsilotlar"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skrinshot"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Skrinshot tayyor."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skrinshot tayyor."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skrinshot olib bo‘lmadi."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Xatoliklar hisoboti tafsilotlari"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tafsilotlari"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Fayl nomi"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Nomi"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Batafsil ta’rif"</string>
diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml
index 2642b89..16ffaff 100644
--- a/packages/Shell/res/values-vi/strings.xml
+++ b/packages/Shell/res/values-vi/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Báo cáo lỗi đang được tạo"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Báo cáo lỗi đã được chụp"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Báo cáo lỗi <xliff:g id="ID">#%d</xliff:g> đang được tạo"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Đã chụp báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Đang thêm thông tin chi tiết vào báo cáo lỗi"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vui lòng đợi…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Vuốt sang trái để chia sẻ báo cáo lỗi của bạn"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Chạm để chia sẻ báo cáo lỗi của bạn"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Nhấn để chia sẻ báo cáo lỗi của bạn"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Các báo cáo lỗi chứa dữ liệu từ nhiều tệp nhật ký khác nhau của hệ thống, bao gồm cả thông tin cá nhân và riêng tư. Chỉ chia sẻ báo cáo lỗi với các ứng dụng và những người mà bạn tin tưởng."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Hiển thị thông báo này vào lần tới"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Báo cáo lỗi"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"chưa được đặt tên"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Chi tiết"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Ảnh chụp màn hình"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Đã chụp ảnh màn hình thành công."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Đã chụp ảnh màn hình thành công."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Không thể chụp ảnh màn hình."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Chi tiết báo cáo lỗi"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Chi tiết báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Tên tệp"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Tiêu đề"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Mô tả chi tiết"</string>
diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml
index c933961..382478e 100644
--- a/packages/Shell/res/values-zh-rCN/strings.xml
+++ b/packages/Shell/res/values-zh-rCN/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"正在生成错误报告"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"已抓取错误报告"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在生成错误报告 <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"已捕获错误报告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在向错误报告添加详细信息"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"请稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑动即可分享错误报告"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"触摸即可分享您的错误报告"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"点按即可分享您的错误报告"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"错误报告包含的数据来自于系统的各个日志文件,其中包含个人信息和隐私信息。请务必只与您信任的应用和用户分享错误报告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再显示这条讯息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"错误报告"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"详细信息"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"屏幕截图"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功截图。"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功截图。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"无法截图。"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"错误报告详细信息"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"错误报告 <xliff:g id="ID">#%d</xliff:g> 详情"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"文件名"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"标题"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"详细说明"</string>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 7a35eef..04b5e48 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"命令介面"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"正在產生錯誤報告"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"已擷取錯誤報告"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"輕觸即可分享您的錯誤報告"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和使用者分享錯誤報告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再顯示這則訊息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"詳細資訊"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕擷取畫面"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"成功拍攝螢幕擷取畫面。"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法擷取螢幕畫面。"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳情"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 的詳情"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"標題"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml
index ec66878..7a1ab77 100644
--- a/packages/Shell/res/values-zh-rTW/strings.xml
+++ b/packages/Shell/res/values-zh-rTW/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"殼層"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"正在產生錯誤報告"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"已擷取錯誤報告"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"輕觸即可分享您的錯誤報告"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告的資料來自系統各個紀錄檔,包括個人和私密資訊。請務必只與您信任的應用程式和使用者分享錯誤報告。"</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次仍顯示這則訊息"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"未命名"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"詳細資料"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"螢幕擷取畫面"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"已成功拍攝螢幕擷取畫面。"</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"已成功拍攝螢幕擷取畫面。"</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"無法拍攝螢幕擷取畫面。"</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"錯誤報告詳細資料"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 的詳細資料"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"檔案名稱"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"標題"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"詳細說明"</string>
diff --git a/packages/Shell/res/values-zu/strings.xml b/packages/Shell/res/values-zu/strings.xml
index c264224..29b7dd83 100644
--- a/packages/Shell/res/values-zu/strings.xml
+++ b/packages/Shell/res/values-zu/strings.xml
@@ -17,12 +17,12 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"I-Shell"</string>
-    <string name="bugreport_in_progress_title" msgid="7409917338223386637">"Kukhiqizwa umbiko wesiphazamisi"</string>
-    <string name="bugreport_finished_title" msgid="2293711546892863898">"Umbiko wesiphazamisi uthwetshuliwe"</string>
+    <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Umbiko wesiphazamisi ongu-<xliff:g id="ID">#%d</xliff:g> uyacutshungulwa"</string>
+    <string name="bugreport_finished_title" msgid="4429132808670114081">"Umbiko wesiphazamisi ongu-<xliff:g id="ID">#%d</xliff:g> uthwetshuliwe"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"Ingeza imininingwane kumbiko wesiphazamisi"</string>
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sicela ulinde..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swayiphela kwesokunxele ukuze wabelane umbiko wesiphazamiso sakho"</string>
-    <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Thinta ukuze wabelane ngombiko wakho wesiphazamisi"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Thepha ukuze wabelane ngombiko wakho wesiphazamisi"</string>
     <string name="bugreport_confirm" msgid="5130698467795669780">"Imibiko yeziphazamisi iqukethe idatha yamafayela wokungena ahlukile wesistimu, afaka ulwazi lomuntu siqu noma lobumfihlo. Yabelana kuphela ngemibiko yeziphazamisi nezinhlelo zokusebenza nabantu obathembayo."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bonisa lo mlayezo ngesikhathi esilandelayo"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Imibiko yeziphazamiso"</string>
@@ -30,9 +30,9 @@
     <string name="bugreport_unnamed" msgid="2800582406842092709">"awunikiwe igama"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Imininingwane"</string>
     <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Isithombe-skrini"</string>
-    <string name="bugreport_screenshot_taken" msgid="7175343181767429088">"Isithombe-skrini sithathwe ngempumelelo."</string>
+    <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Isithombe-skrini sithathwe ngempumelelo."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Isithombe-skrini asikwazanga ukuthathwa."</string>
-    <string name="bugreport_info_dialog_title" msgid="3113549839798564645">"Imininingwane yombiko wesiphazamisi"</string>
+    <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Imininingwane yombiko wesiphazamisi ongu-<xliff:g id="ID">#%d</xliff:g>"</string>
     <string name="bugreport_info_name" msgid="4414036021935139527">"Igama lefayela"</string>
     <string name="bugreport_info_title" msgid="5599558206004371052">"Isihloko"</string>
     <string name="bugreport_info_description" msgid="4117088998733546784">"Incazelo enemininingwane"</string>
diff --git a/packages/Shell/res/values/strings.xml b/packages/Shell/res/values/strings.xml
index e8e607b..c26b549 100644
--- a/packages/Shell/res/values/strings.xml
+++ b/packages/Shell/res/values/strings.xml
@@ -13,14 +13,13 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label">Shell</string>
 
     <!-- Title of notification indicating a bugreport is being generated. [CHAR LIMIT=50] -->
-    <string name="bugreport_in_progress_title">Bug report is being generated</string>
+    <string name="bugreport_in_progress_title">Bug report <xliff:g id="id">#%d</xliff:g> is being generated</string>
     <!-- Title of notification indicating a bugreport has been successfully captured. [CHAR LIMIT=50] -->
-    <string name="bugreport_finished_title">Bug report captured</string>
+    <string name="bugreport_finished_title">Bug report <xliff:g id="id">#%d</xliff:g> captured</string>
     <!-- Title of notification indicating a bugreport is being updated before it can be shared. [CHAR LIMIT=50] -->
     <string name="bugreport_updating_title">Adding details to the bug report</string>
     <!-- Content notification indicating a bugreport is being updated before it can be shared, asking the user to wait [CHAR LIMIT=50] -->
@@ -53,12 +52,12 @@
     <string name="bugreport_screenshot_action">Screenshot</string>
 
     <!-- Toast message sent when the a screenshot for the bug report was taken successfully. -->
-    <string name="bugreport_screenshot_taken">Screenshot taken succesfully.</string>
+    <string name="bugreport_screenshot_taken">Screenshot taken successfully.</string>
     <!-- Toast message sent when the a screenshot for the bug report was not taken due to an error. -->
     <string name="bugreport_screenshot_failed">Screenshot could not be taken.</string>
 
     <!--  Title of the dialog asking for user-defined bug report details like name, title, and description. -->
-    <string name="bugreport_info_dialog_title">Bug report details</string>
+    <string name="bugreport_info_dialog_title">Bug report <xliff:g id="id">#%d</xliff:g> details</string>
 
     <!-- Text of the hint asking for the bug report name, which when set will define a suffix in the
          bug report file names. [CHAR LIMIT=30] -->
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 78197b3..9926ae5 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -88,8 +88,8 @@
  * <p>
  * The workflow is:
  * <ol>
- * <li>When {@code dumpstate} starts, it sends a {@code BUGREPORT_STARTED} with its pid and the
- * estimated total effort.
+ * <li>When {@code dumpstate} starts, it sends a {@code BUGREPORT_STARTED} with a sequential id,
+ * its pid, and the estimated total effort.
  * <li>{@link BugreportReceiver} receives the intent and delegates it to this service.
  * <li>Upon start, this service:
  * <ol>
@@ -132,6 +132,7 @@
 
     static final String EXTRA_BUGREPORT = "android.intent.extra.BUGREPORT";
     static final String EXTRA_SCREENSHOT = "android.intent.extra.SCREENSHOT";
+    static final String EXTRA_ID = "android.intent.extra.ID";
     static final String EXTRA_PID = "android.intent.extra.PID";
     static final String EXTRA_MAX = "android.intent.extra.MAX";
     static final String EXTRA_NAME = "android.intent.extra.NAME";
@@ -157,7 +158,7 @@
     static final long POLLING_FREQUENCY = 2 * DateUtils.SECOND_IN_MILLIS;
 
     /** How long (in ms) a dumpstate process will be monitored if it didn't show progress. */
-    private static final long INACTIVITY_TIMEOUT = 3 * DateUtils.MINUTE_IN_MILLIS;
+    private static final long INACTIVITY_TIMEOUT = 10 * DateUtils.MINUTE_IN_MILLIS;
 
     /** System properties used for monitoring progress. */
     private static final String DUMPSTATE_PREFIX = "dumpstate.";
@@ -177,7 +178,7 @@
      */
     private static final String SCREENSHOT_DIR = "bugreports";
 
-    /** Managed dumpstate processes (keyed by pid) */
+    /** Managed dumpstate processes (keyed by id) */
     private final SparseArray<BugreportInfo> mProcesses = new SparseArray<>();
 
     private Context mContext;
@@ -222,7 +223,7 @@
         }
 
         // If service is killed it cannot be recreated because it would not know which
-        // dumpstate PIDs it would have to watch.
+        // dumpstate IDs it would have to watch.
         return START_NOT_STICKY;
     }
 
@@ -299,38 +300,41 @@
             }
             final String action = intent.getAction();
             final int pid = intent.getIntExtra(EXTRA_PID, 0);
+            // TODO: temporarily using pid as id until test cases and dumpstate are changed.
+            final int id = intent.getIntExtra(EXTRA_ID, pid);
             final int max = intent.getIntExtra(EXTRA_MAX, -1);
             final String name = intent.getStringExtra(EXTRA_NAME);
 
-            if (DEBUG) Log.v(TAG, "action: " + action + ", name: " + name + ", pid: " + pid
-                    + ", max: "+ max);
+            if (DEBUG)
+                Log.v(TAG, "action: " + action + ", name: " + name + ", id: " + id + ", pid: "
+                        + pid + ", max: " + max);
             switch (action) {
                 case INTENT_BUGREPORT_STARTED:
-                    if (!startProgress(name, pid, max)) {
+                    if (!startProgress(name, id, pid, max)) {
                         stopSelfWhenDone();
                         return;
                     }
                     poll();
                     break;
                 case INTENT_BUGREPORT_FINISHED:
-                    if (pid == 0) {
+                    if (id == 0) {
                         // Shouldn't happen, unless BUGREPORT_FINISHED is received from a legacy,
                         // out-of-sync dumpstate process.
-                        Log.w(TAG, "Missing " + EXTRA_PID + " on intent " + intent);
+                        Log.w(TAG, "Missing " + EXTRA_ID + " on intent " + intent);
                     }
-                    onBugreportFinished(pid, intent);
+                    onBugreportFinished(id, intent);
                     break;
                 case INTENT_BUGREPORT_INFO_LAUNCH:
-                    launchBugreportInfoDialog(pid);
+                    launchBugreportInfoDialog(id);
                     break;
                 case INTENT_BUGREPORT_SCREENSHOT:
-                    takeScreenshot(pid, true);
+                    takeScreenshot(id, true);
                     break;
                 case INTENT_BUGREPORT_SHARE:
-                    shareBugreport(pid, (BugreportInfo) intent.getParcelableExtra(EXTRA_INFO));
+                    shareBugreport(id, (BugreportInfo) intent.getParcelableExtra(EXTRA_INFO));
                     break;
                 case INTENT_BUGREPORT_CANCEL:
-                    cancel(pid);
+                    cancel(id);
                     break;
                 default:
                     Log.w(TAG, "Unsupported intent: " + action);
@@ -367,10 +371,10 @@
         }
     }
 
-    private BugreportInfo getInfo(int pid) {
-        final BugreportInfo info = mProcesses.get(pid);
+    private BugreportInfo getInfo(int id) {
+        final BugreportInfo info = mProcesses.get(id);
         if (info == null) {
-            Log.w(TAG, "Not monitoring process with PID " + pid);
+            Log.w(TAG, "Not monitoring process with ID " + id);
         }
         return info;
     }
@@ -381,10 +385,14 @@
      *
      * @return whether it succeeded or not.
      */
-    private boolean startProgress(String name, int pid, int max) {
+    private boolean startProgress(String name, int id, int pid, int max) {
         if (name == null) {
             Log.w(TAG, "Missing " + EXTRA_NAME + " on start intent");
         }
+        if (id == -1) {
+            Log.e(TAG, "Missing " + EXTRA_ID + " on start intent");
+            return false;
+        }
         if (pid == -1) {
             Log.e(TAG, "Missing " + EXTRA_PID + " on start intent");
             return false;
@@ -394,14 +402,14 @@
             return false;
         }
 
-        final BugreportInfo info = new BugreportInfo(mContext, pid, name, max);
-        if (mProcesses.indexOfKey(pid) >= 0) {
-            Log.w(TAG, "PID " + pid + " already watched");
+        final BugreportInfo info = new BugreportInfo(mContext, id, pid, name, max);
+        if (mProcesses.indexOfKey(id) >= 0) {
+            Log.w(TAG, "ID " + id + " already watched");
         } else {
-            mProcesses.put(info.pid, info);
+            mProcesses.put(info.id, info);
         }
         // Take initial screenshot.
-        takeScreenshot(pid, false);
+        takeScreenshot(id, false);
         updateProgress(info);
         return true;
     }
@@ -423,22 +431,22 @@
                 com.android.internal.R.string.cancel), newCancelIntent(mContext, info)).build();
         final Intent infoIntent = new Intent(mContext, BugreportProgressService.class);
         infoIntent.setAction(INTENT_BUGREPORT_INFO_LAUNCH);
-        infoIntent.putExtra(EXTRA_PID, info.pid);
+        infoIntent.putExtra(EXTRA_ID, info.id);
         final Action infoAction = new Action.Builder(null,
                 mContext.getString(R.string.bugreport_info_action),
-                PendingIntent.getService(mContext, info.pid, infoIntent,
+                PendingIntent.getService(mContext, info.id, infoIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT)).build();
         final Intent screenshotIntent = new Intent(mContext, BugreportProgressService.class);
         screenshotIntent.setAction(INTENT_BUGREPORT_SCREENSHOT);
-        screenshotIntent.putExtra(EXTRA_PID, info.pid);
+        screenshotIntent.putExtra(EXTRA_ID, info.id);
         PendingIntent screenshotPendingIntent = mTakingScreenshot ? null : PendingIntent
-                .getService(mContext, info.pid, screenshotIntent,
+                .getService(mContext, info.id, screenshotIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT);
         final Action screenshotAction = new Action.Builder(null,
                 mContext.getString(R.string.bugreport_screenshot_action),
                 screenshotPendingIntent).build();
 
-        final String title = mContext.getString(R.string.bugreport_in_progress_title);
+        final String title = mContext.getString(R.string.bugreport_in_progress_title, info.id);
 
         final String name =
                 info.name != null ? info.name : mContext.getString(R.string.bugreport_unnamed);
@@ -464,8 +472,8 @@
                     + info + ")");
             return;
         }
-        Log.v(TAG, "Sending 'Progress' notification for pid " + info.pid + ": " + percentText);
-        NotificationManager.from(mContext).notify(TAG, info.pid, notification);
+        Log.v(TAG, "Sending 'Progress' notification for id " + info.id + ": " + percentText);
+        NotificationManager.from(mContext).notify(TAG, info.id, notification);
     }
 
     /**
@@ -474,38 +482,38 @@
     private static PendingIntent newCancelIntent(Context context, BugreportInfo info) {
         final Intent intent = new Intent(INTENT_BUGREPORT_CANCEL);
         intent.setClass(context, BugreportProgressService.class);
-        intent.putExtra(EXTRA_PID, info.pid);
-        return PendingIntent.getService(context, info.pid, intent,
+        intent.putExtra(EXTRA_ID, info.id);
+        return PendingIntent.getService(context, info.id, intent,
                 PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
     /**
      * Finalizes the progress on a given bugreport and cancel its notification.
      */
-    private void stopProgress(int pid) {
-        if (mProcesses.indexOfKey(pid) < 0) {
-            Log.w(TAG, "PID not watched: " + pid);
+    private void stopProgress(int id) {
+        if (mProcesses.indexOfKey(id) < 0) {
+            Log.w(TAG, "ID not watched: " + id);
         } else {
-            Log.d(TAG, "Removing PID " + pid);
-            mProcesses.remove(pid);
+            Log.d(TAG, "Removing ID " + id);
+            mProcesses.remove(id);
         }
         stopSelfWhenDone();
-        Log.v(TAG, "stopProgress(" + pid + "): cancel notification");
-        NotificationManager.from(mContext).cancel(TAG, pid);
+        Log.v(TAG, "stopProgress(" + id + "): cancel notification");
+        NotificationManager.from(mContext).cancel(TAG, id);
     }
 
     /**
      * Cancels a bugreport upon user's request.
      */
-    private void cancel(int pid) {
-        Log.v(TAG, "cancel: pid=" + pid);
-        final BugreportInfo info = getInfo(pid);
+    private void cancel(int id) {
+        Log.v(TAG, "cancel: ID=" + id);
+        final BugreportInfo info = getInfo(id);
         if (info != null && !info.finished) {
-            Log.i(TAG, "Cancelling bugreport service (pid=" + pid + ") on user's request");
+            Log.i(TAG, "Cancelling bugreport service (ID=" + id + ") on user's request");
             setSystemProperty(CTL_STOP, BUGREPORT_SERVICE);
             deleteScreenshots(info);
         }
-        stopProgress(pid);
+        stopProgress(id);
     }
 
     /**
@@ -522,14 +530,15 @@
         for (int i = 0; i < total; i++) {
             final BugreportInfo info = mProcesses.valueAt(i);
             if (info == null) {
-                Log.wtf(TAG, "pollProgress(): null info at index " + i + "(pid = "
+                Log.wtf(TAG, "pollProgress(): null info at index " + i + "(ID = "
                         + mProcesses.keyAt(i) + ")");
                 continue;
             }
 
             final int pid = info.pid;
+            final int id = info.id;
             if (info.finished) {
-                if (DEBUG) Log.v(TAG, "Skipping finished process " + pid);
+                if (DEBUG) Log.v(TAG, "Skipping finished process " + pid + "(id: " + id + ")");
                 continue;
             }
             activeProcesses++;
@@ -544,13 +553,13 @@
 
             if (progressChanged || maxChanged) {
                 if (progressChanged) {
-                    if (DEBUG) Log.v(TAG, "Updating progress for PID " + pid + " from "
-                            + info.progress + " to " + progress);
+                    if (DEBUG) Log.v(TAG, "Updating progress for PID " + pid + "(id: " + id
+                            + ") from " + info.progress + " to " + progress);
                     info.progress = progress;
                 }
                 if (maxChanged) {
-                    Log.i(TAG, "Updating max progress for PID " + pid + " from " + info.max
-                            + " to " + max);
+                    Log.i(TAG, "Updating max progress for PID " + pid + "(id: " + id
+                            + ") from " + info.max + " to " + max);
                     info.max = max;
                 }
                 info.lastUpdate = System.currentTimeMillis();
@@ -558,9 +567,9 @@
             } else {
                 long inactiveTime = System.currentTimeMillis() - info.lastUpdate;
                 if (inactiveTime >= INACTIVITY_TIMEOUT) {
-                    Log.w(TAG, "No progress update for process " + pid + " since "
+                    Log.w(TAG, "No progress update for PID " + pid + " since "
                             + info.getFormattedLastUpdate());
-                    stopProgress(info.pid);
+                    stopProgress(info.id);
                 }
             }
         }
@@ -572,19 +581,22 @@
      * Fetches a {@link BugreportInfo} for a given process and launches a dialog where the user can
      * change its values.
      */
-    private void launchBugreportInfoDialog(int pid) {
+    private void launchBugreportInfoDialog(int id) {
         // Copy values so it doesn't lock mProcesses while UI is being updated
         final String name, title, description;
-        final BugreportInfo info = getInfo(pid);
+        final BugreportInfo info = getInfo(id);
         if (info == null) {
+            // Most likely am killed Shell before user tapped the notification. Since system might
+            // be too busy anwyays, it's better to ignore the notification and switch back to the
+            // non-interactive mode (where the bugerport will be shared upon completion).
+            Log.d(TAG, "launchBugreportInfoDialog(" + id + "): cancel notification");
+            // TODO: add test case to make sure notification is canceled.
+            NotificationManager.from(mContext).cancel(TAG, id);
             return;
         }
-        name = info.name;
-        title = info.title;
-        description = info.description;
 
         collapseNotificationBar();
-        mInfoDialog.initialize(mContext, pid, name, title, description);
+        mInfoDialog.initialize(mContext, info);
     }
 
     /**
@@ -597,7 +609,16 @@
      * Typical usage is delaying when taken from the notification action, and taking it right away
      * upon receiving a {@link #INTENT_BUGREPORT_STARTED}.
      */
-    private void takeScreenshot(int pid, boolean delayed) {
+    private void takeScreenshot(int id, boolean delayed) {
+        if (getInfo(id) == null) {
+            // Most likely am killed Shell before user tapped the notification. Since system might
+            // be too busy anwyays, it's better to ignore the notification and switch back to the
+            // non-interactive mode (where the bugerport will be shared upon completion).
+            Log.d(TAG, "takeScreenshot(" + id + ", " + delayed + "): cancel notification");
+            // TODO: add test case to make sure notification is canceled.
+            NotificationManager.from(mContext).cancel(TAG, id);
+            return;
+        }
         setTakingScreenshot(true);
         if (delayed) {
             collapseNotificationBar();
@@ -608,28 +629,28 @@
             // Show a toast just once, otherwise it might be captured in the screenshot.
             Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
 
-            takeScreenshot(pid, SCREENSHOT_DELAY_SECONDS);
+            takeScreenshot(id, SCREENSHOT_DELAY_SECONDS);
         } else {
-            takeScreenshot(pid, 0);
+            takeScreenshot(id, 0);
         }
     }
 
     /**
      * Takes a screenshot after {@code delay} seconds.
      */
-    private void takeScreenshot(int pid, int delay) {
+    private void takeScreenshot(int id, int delay) {
         if (delay > 0) {
-            Log.d(TAG, "Taking screenshot for " + pid + " in " + delay + " seconds");
+            Log.d(TAG, "Taking screenshot for " + id + " in " + delay + " seconds");
             final Message msg = mMainHandler.obtainMessage();
             msg.what = MSG_DELAYED_SCREENSHOT;
-            msg.arg1 = pid;
+            msg.arg1 = id;
             msg.arg2 = delay - 1;
             mMainHandler.sendMessageDelayed(msg, DateUtils.SECOND_IN_MILLIS);
             return;
         }
 
         // It's time to take the screenshot: let the proper thread handle it
-        final BugreportInfo info = getInfo(pid);
+        final BugreportInfo info = getInfo(id);
         if (info == null) {
             return;
         }
@@ -638,7 +659,7 @@
 
         final Message requestMsg = new Message();
         requestMsg.what = MSG_SCREENSHOT_REQUEST;
-        requestMsg.arg1 = pid;
+        requestMsg.arg1 = id;
         requestMsg.obj = screenshotPath;
         mScreenshotHandler.sendMessage(requestMsg);
     }
@@ -715,30 +736,30 @@
      */
     private void stopSelfWhenDone() {
         if (mProcesses.size() > 0) {
-            if (DEBUG) Log.v(TAG, "Staying alive, waiting for pids " + mProcesses);
+            if (DEBUG) Log.d(TAG, "Staying alive, waiting for IDs " + mProcesses);
             return;
         }
-        Log.v(TAG, "No more pids to handle, shutting down");
+        Log.v(TAG, "No more processes to handle, shutting down");
         stopSelf();
     }
 
     /**
      * Handles the BUGREPORT_FINISHED intent sent by {@code dumpstate}.
      */
-    private void onBugreportFinished(int pid, Intent intent) {
+    private void onBugreportFinished(int id, Intent intent) {
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
         if (bugreportFile == null) {
             // Should never happen, dumpstate always set the file.
             Log.wtf(TAG, "Missing " + EXTRA_BUGREPORT + " on intent " + intent);
             return;
         }
-        mInfoDialog.onBugreportFinished(pid);
-        BugreportInfo info = getInfo(pid);
+        mInfoDialog.onBugreportFinished(id);
+        BugreportInfo info = getInfo(id);
         if (info == null) {
             // Happens when BUGREPORT_FINISHED was received without a BUGREPORT_STARTED first.
-            Log.v(TAG, "Creating info for untracked pid " + pid);
-            info = new BugreportInfo(mContext, pid);
-            mProcesses.put(pid, info);
+            Log.v(TAG, "Creating info for untracked ID " + id);
+            info = new BugreportInfo(mContext, id);
+            mProcesses.put(id, info);
         }
         info.renameScreenshots(mScreenshotsDir);
         info.bugreportFile = bugreportFile;
@@ -765,7 +786,7 @@
         if (!info.bugreportFile.exists() || !info.bugreportFile.canRead()) {
             Log.e(TAG, "Could not read bugreport file " + info.bugreportFile);
             Toast.makeText(context, R.string.bugreport_unreadable_text, Toast.LENGTH_LONG).show();
-            stopProgress(info.pid);
+            stopProgress(info.id);
             return;
         }
 
@@ -837,12 +858,12 @@
      * Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
      * intent, but issuing a warning dialog the first time.
      */
-    private void shareBugreport(int pid, BugreportInfo sharedInfo) {
-        BugreportInfo info = getInfo(pid);
+    private void shareBugreport(int id, BugreportInfo sharedInfo) {
+        BugreportInfo info = getInfo(id);
         if (info == null) {
             // Service was terminated but notification persisted
             info = sharedInfo;
-            Log.d(TAG, "shareBugreport(): no info for PID " + pid + " on managed processes ("
+            Log.d(TAG, "shareBugreport(): no info for ID " + id + " on managed processes ("
                     + mProcesses + "), using info from intent instead (" + info + ")");
         }
 
@@ -863,7 +884,7 @@
         mContext.startActivity(notifIntent);
 
         // ... and stop watching this process.
-        stopProgress(pid);
+        stopProgress(id);
     }
 
     /**
@@ -877,16 +898,16 @@
         final Intent shareIntent = new Intent(INTENT_BUGREPORT_SHARE);
         shareIntent.setClass(context, BugreportProgressService.class);
         shareIntent.setAction(INTENT_BUGREPORT_SHARE);
-        shareIntent.putExtra(EXTRA_PID, info.pid);
+        shareIntent.putExtra(EXTRA_ID, info.id);
         shareIntent.putExtra(EXTRA_INFO, info);
 
-        final String title = context.getString(R.string.bugreport_finished_title);
+        final String title = context.getString(R.string.bugreport_finished_title, info.id);
         final Notification.Builder builder = new Notification.Builder(context)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                 .setContentTitle(title)
                 .setTicker(title)
                 .setContentText(context.getString(R.string.bugreport_finished_text))
-                .setContentIntent(PendingIntent.getService(context, info.pid, shareIntent,
+                .setContentIntent(PendingIntent.getService(context, info.id, shareIntent,
                         PendingIntent.FLAG_UPDATE_CURRENT))
                 .setDeleteIntent(newCancelIntent(context, info))
                 .setLocalOnly(true)
@@ -897,8 +918,8 @@
             builder.setContentInfo(info.name);
         }
 
-        Log.v(TAG, "Sending 'Share' notification for pid " + info.pid + ": " + title);
-        NotificationManager.from(context).notify(TAG, info.pid, builder.build());
+        Log.v(TAG, "Sending 'Share' notification for ID " + info.id + ": " + title);
+        NotificationManager.from(context).notify(TAG, info.id, builder.build());
     }
 
     /**
@@ -906,7 +927,7 @@
      * finishes - at this point there is nothing to be done other than waiting, hence it has no
      * pending action.
      */
-    private static void sendBugreportBeingUpdatedNotification(Context context, int pid) {
+    private static void sendBugreportBeingUpdatedNotification(Context context, int id) {
         final String title = context.getString(R.string.bugreport_updating_title);
         final Notification.Builder builder = new Notification.Builder(context)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
@@ -916,8 +937,8 @@
                 .setLocalOnly(true)
                 .setColor(context.getColor(
                         com.android.internal.R.color.system_notification_accent_color));
-        Log.v(TAG, "Sending 'Updating zip' notification for pid " + pid + ": " + title);
-        NotificationManager.from(context).notify(TAG, pid, builder.build());
+        Log.v(TAG, "Sending 'Updating zip' notification for ID " + id + ": " + title);
+        NotificationManager.from(context).notify(TAG, id, builder.build());
     }
 
     /**
@@ -985,7 +1006,7 @@
 
         // It's not possible to add a new entry into an existing file, so we need to create a new
         // zip, copy all entries, then rename it.
-        sendBugreportBeingUpdatedNotification(context, info.pid); // ...and that takes time
+        sendBugreportBeingUpdatedNotification(context, info.id); // ...and that takes time
         final File dir = info.bugreportFile.getParentFile();
         final File tmpZip = new File(dir, "tmp-" + info.bugreportFile.getName());
         Log.d(TAG, "Writing temporary zip file (" + tmpZip + ") with title and/or description");
@@ -1113,14 +1134,14 @@
     /**
      * Updates the user-provided details of a bugreport.
      */
-    private void updateBugreportInfo(int pid, String name, String title, String description) {
-        final BugreportInfo info = getInfo(pid);
+    private void updateBugreportInfo(int id, String name, String title, String description) {
+        final BugreportInfo info = getInfo(id);
         if (info == null) {
             return;
         }
         info.title = title;
         info.description = description;
-        if (name != null && !info.name.equals(name)) {
+        if (name != null && !name.equals(info.name)) {
             info.name = name;
             updateProgress(info);
         }
@@ -1179,6 +1200,7 @@
         private EditText mInfoDescription;
         private AlertDialog mDialog;
         private Button mOkButton;
+        private int mId;
         private int mPid;
 
         /**
@@ -1207,8 +1229,7 @@
         /**
          * Sets its internal state and displays the dialog.
          */
-        private void initialize(Context context, int pid, String name, String title,
-                String description) {
+        private void initialize(Context context, BugreportInfo info) {
             // First initializes singleton.
             if (mDialog == null) {
                 @SuppressLint("InflateParams")
@@ -1232,7 +1253,7 @@
 
                 mDialog = new AlertDialog.Builder(context)
                         .setView(view)
-                        .setTitle(context.getString(R.string.bugreport_info_dialog_title))
+                        .setTitle(context.getString(R.string.bugreport_info_dialog_title, info.id))
                         .setCancelable(false)
                         .setPositiveButton(context.getString(com.android.internal.R.string.ok),
                                 null)
@@ -1258,16 +1279,17 @@
             }
 
             // Then set fields.
-            mSavedName = mTempName = name;
-            mPid = pid;
-            if (!TextUtils.isEmpty(name)) {
-                mInfoName.setText(name);
+            mSavedName = mTempName = info.name;
+            mId = info.id;
+            mPid = info.pid;
+            if (!TextUtils.isEmpty(info.name)) {
+                mInfoName.setText(info.name);
             }
-            if (!TextUtils.isEmpty(title)) {
-                mInfoTitle.setText(title);
+            if (!TextUtils.isEmpty(info.title)) {
+                mInfoTitle.setText(info.title);
             }
-            if (!TextUtils.isEmpty(description)) {
-                mInfoDescription.setText(description);
+            if (!TextUtils.isEmpty(info.description)) {
+                mInfoDescription.setText(info.description);
             }
 
             // And finally display it.
@@ -1290,7 +1312,7 @@
                         final String title = mInfoTitle.getText().toString();
                         final String description = mInfoDescription.getText().toString();
 
-                        updateBugreportInfo(mPid, name, title, description);
+                        updateBugreportInfo(mId, name, title, description);
                         mDialog.dismiss();
                     }
                 });
@@ -1328,7 +1350,7 @@
             // Must update system property for the cases where dumpstate finishes
             // while the user is still entering other fields (like title or
             // description)
-            setBugreportNameProperty(mPid, name);
+            setBugreportNameProperty(mId, name);
         }
 
        /**
@@ -1337,7 +1359,7 @@
          * <p>Once the bugreport is finished dumpstate has already generated the final files, so
          * changing the name would have no effect.
          */
-        private void onBugreportFinished(int pid) {
+        private void onBugreportFinished(int id) {
             if (mInfoName != null) {
                 mInfoName.setEnabled(false);
                 mInfoName.setText(mSavedName);
@@ -1353,6 +1375,11 @@
         private final Context context;
 
         /**
+         * Sequential, user-friendly id used to identify the bugreport.
+         */
+        final int id;
+
+        /**
          * {@code pid} of the {@code dumpstate} process generating the bugreport.
          */
         final int pid;
@@ -1426,8 +1453,9 @@
         /**
          * Constructor for tracked bugreports - typically called upon receiving BUGREPORT_STARTED.
          */
-        BugreportInfo(Context context, int pid, String name, int max) {
+        BugreportInfo(Context context, int id, int pid, String name, int max) {
             this.context = context;
+            this.id = id;
             this.pid = pid;
             this.name = name;
             this.max = max;
@@ -1437,8 +1465,8 @@
          * Constructor for untracked bugreports - typically called upon receiving BUGREPORT_FINISHED
          * without a previous call to BUGREPORT_STARTED.
          */
-        BugreportInfo(Context context, int pid) {
-            this(context, pid, null, 0);
+        BugreportInfo(Context context, int id) {
+            this(context, id, id, null, 0);
             this.finished = true;
         }
 
@@ -1494,7 +1522,7 @@
         @Override
         public String toString() {
             final float percent = ((float) progress * 100 / max);
-            return "pid: " + pid + ", name: " + name + ", finished: " + finished
+            return "id: " + id + ", pid: " + pid + ", name: " + name + ", finished: " + finished
                     + "\n\ttitle: " + title + "\n\tdescription: " + description
                     + "\n\tfile: " + bugreportFile + "\n\tscreenshots: " + screenshotFiles
                     + "\n\tprogress: " + progress + "/" + max + "(" + percent + ")"
@@ -1506,6 +1534,7 @@
         // Parcelable contract
         protected BugreportInfo(Parcel in) {
             context = null;
+            id = in.readInt();
             pid = in.readInt();
             name = in.readString();
             title = in.readString();
@@ -1527,6 +1556,7 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(id);
             dest.writeInt(pid);
             dest.writeString(name);
             dest.writeString(title);
diff --git a/packages/Shell/src/com/android/shell/RemoteBugreportReceiver.java b/packages/Shell/src/com/android/shell/RemoteBugreportReceiver.java
index 6f783a1..be54b43 100644
--- a/packages/Shell/src/com/android/shell/RemoteBugreportReceiver.java
+++ b/packages/Shell/src/com/android/shell/RemoteBugreportReceiver.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.UserHandle;
+import android.text.format.DateUtils;
 
 /**
  * Receiver that handles finished remote bugreports, by re-sending
@@ -43,12 +44,16 @@
     private static final String EXTRA_REMOTE_BUGREPORT_HASH =
             "android.intent.extra.REMOTE_BUGREPORT_HASH";
 
-    /** Always keep just the last remote bugreport zip file */
-    private static final int MIN_KEEP_COUNT = 1;
+    /** Always keep just the last remote bugreport's files around. */
+    private static final int REMOTE_BUGREPORT_FILES_AMOUNT = 3;
+
+    /** Always keep remote bugreport files created in the last day. */
+    private static final long MIN_KEEP_AGE = DateUtils.DAY_IN_MILLIS;
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        cleanupOldFiles(this, intent, INTENT_REMOTE_BUGREPORT_FINISHED, MIN_KEEP_COUNT, 0);
+        cleanupOldFiles(this, intent, INTENT_REMOTE_BUGREPORT_FINISHED,
+                REMOTE_BUGREPORT_FILES_AMOUNT, MIN_KEEP_AGE);
 
         final File bugreportFile = getFileExtra(intent, EXTRA_BUGREPORT);
         final Uri bugreportUri = getUri(context, bugreportFile);
diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
index ea85c61..8c62670 100644
--- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
+++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java
@@ -36,6 +36,7 @@
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.SortedSet;
@@ -58,6 +59,7 @@
 import android.service.notification.StatusBarNotification;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.test.InstrumentationTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.text.TextUtils;
@@ -113,7 +115,7 @@
     private static final String NO_NAME = null;
     private static final String NO_SCREENSHOT = null;
     private static final String NO_TITLE = null;
-    private static final Integer NO_PID = null;
+    private static final int NO_PID = 0;
     private static final boolean RENAMED_SCREENSHOTS = true;
     private static final boolean DIDNT_RENAME_SCREENSHOTS = false;
 
@@ -159,16 +161,20 @@
         sendBugreportStarted(1000);
         waitForScreenshotButtonEnabled(true);
 
-        assertProgressNotification(NAME, "0.00%");
+        final NumberFormat nf = NumberFormat.getPercentInstance();
+        nf.setMinimumFractionDigits(2);
+        nf.setMaximumFractionDigits(2);
+
+        assertProgressNotification(NAME, nf.format(0));
 
         SystemProperties.set(PROGRESS_PROPERTY, "108");
-        assertProgressNotification(NAME, "10.80%");
+        assertProgressNotification(NAME, nf.format(0.108));
 
         SystemProperties.set(PROGRESS_PROPERTY, "500");
-        assertProgressNotification(NAME, "50.00%");
+        assertProgressNotification(NAME, nf.format(0.50));
 
         SystemProperties.set(MAX_PROPERTY, "2000");
-        assertProgressNotification(NAME, "25.00%");
+        assertProgressNotification(NAME, nf.format(0.25));
 
         Bundle extras =
                 sendBugreportFinishedAndGetSharedIntent(PID, mPlainTextPath, mScreenshotPath);
@@ -198,11 +204,11 @@
         sendBugreportFinished(PID, mPlainTextPath, mScreenshotPath);
 
         if (serviceDies) {
-            waitShareNotification();
+            waitShareNotification(PID);
             killService();
         }
 
-        Bundle extras = acceptBugreportAndGetSharedIntent();
+        Bundle extras = acceptBugreportAndGetSharedIntent(PID);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, ZIP_FILE,
                 NAME, NO_TITLE, NO_DESCRIPTION, 2, RENAMED_SCREENSHOTS);
 
@@ -222,7 +228,7 @@
 
         sendBugreportStarted(1000);
         sendBugreportFinished(PID, mPlainTextPath, NO_SCREENSHOT);
-        waitShareNotification();
+        waitShareNotification(PID);
 
         // There's no indication in the UI about the screenshot finish, so just sleep like a baby...
         Thread.sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS);
@@ -231,7 +237,7 @@
             killService();
         }
 
-        Bundle extras = acceptBugreportAndGetSharedIntent();
+        Bundle extras = acceptBugreportAndGetSharedIntent(PID);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, PID, ZIP_FILE,
                 NAME, NO_TITLE, NO_DESCRIPTION, 1, RENAMED_SCREENSHOTS);
 
@@ -243,7 +249,7 @@
         sendBugreportStarted(1000);
         waitForScreenshotButtonEnabled(true);
 
-        DetailsUi detailsUi = new DetailsUi(mUiBot);
+        DetailsUi detailsUi = new DetailsUi(mUiBot, PID);
 
         // Check initial name.
         String actualName = detailsUi.nameField.getText().toString();
@@ -296,7 +302,7 @@
         sendBugreportStarted(1000);
         waitForScreenshotButtonEnabled(true);
 
-        DetailsUi detailsUi = new DetailsUi(mUiBot);
+        DetailsUi detailsUi = new DetailsUi(mUiBot, PID);
 
         // Check initial name.
         String actualName = detailsUi.nameField.getText().toString();
@@ -326,7 +332,7 @@
         sendBugreportStarted(1000);
         waitForScreenshotButtonEnabled(true);
 
-        DetailsUi detailsUi = new DetailsUi(mUiBot);
+        DetailsUi detailsUi = new DetailsUi(mUiBot, PID);
 
         detailsUi.nameField.setText("");
         detailsUi.titleField.setText("");
@@ -363,14 +369,14 @@
             waitForScreenshotButtonEnabled(true);
         }
 
-        DetailsUi detailsUi = new DetailsUi(mUiBot);
+        DetailsUi detailsUi = new DetailsUi(mUiBot, PID);
 
         // Finish the bugreport while user's still typing the name.
         detailsUi.nameField.setText(NEW_NAME);
         sendBugreportFinished(PID, mPlainTextPath, mScreenshotPath);
 
         // Wait until the share notification is received...
-        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title));
+        waitShareNotification(PID);
         // ...then close notification bar.
         mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
 
@@ -384,7 +390,7 @@
         detailsUi.clickOk();
 
         // Finally, share bugreport.
-        Bundle extras = acceptBugreportAndGetSharedIntent();
+        Bundle extras = acceptBugreportAndGetSharedIntent(PID);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, PID, TITLE,
                 NAME, TITLE, mDescription, 1, RENAMED_SCREENSHOTS);
 
@@ -397,7 +403,7 @@
 
         // Send notification and click on share.
         sendBugreportFinished(NO_PID, mPlainTextPath, null);
-        acceptBugreport();
+        acceptBugreport(NO_PID);
 
         // Handle the warning
         mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm));
@@ -421,7 +427,7 @@
     public void testShareBugreportAfterServiceDies() throws Exception {
         sendBugreportFinished(NO_PID, mPlainTextPath, NO_SCREENSHOT);
         killService();
-        Bundle extras = acceptBugreportAndGetSharedIntent();
+        Bundle extras = acceptBugreportAndGetSharedIntent(NO_PID);
         assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
     }
 
@@ -457,14 +463,14 @@
     private void assertProgressNotification(String name, String percent) {
         // TODO: it currently looks for 3 distinct objects, without taking advantage of their
         // relationship.
-        openProgressNotification();
+        openProgressNotification(PID);
         Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'");
         mUiBot.getObject(name);
         mUiBot.getObject(percent);
     }
 
-    private void openProgressNotification() {
-        String title = mContext.getString(R.string.bugreport_in_progress_title);
+    private void openProgressNotification(int pid) {
+        String title = mContext.getString(R.string.bugreport_in_progress_title, pid);
         Log.v(TAG, "Looking for progress notification title: '" + title + "'");
         mUiBot.getNotification(title);
     }
@@ -494,7 +500,7 @@
      */
     private Bundle sendBugreportFinishedAndGetSharedIntent(String bugreportPath,
             String screenshotPath) {
-        return sendBugreportFinishedAndGetSharedIntent(null, bugreportPath, screenshotPath);
+        return sendBugreportFinishedAndGetSharedIntent(NO_PID, bugreportPath, screenshotPath);
     }
 
     /**
@@ -502,10 +508,10 @@
      *
      * @return extras sent in the shared intent.
      */
-    private Bundle sendBugreportFinishedAndGetSharedIntent(Integer pid, String bugreportPath,
+    private Bundle sendBugreportFinishedAndGetSharedIntent(int pid, String bugreportPath,
             String screenshotPath) {
         sendBugreportFinished(pid, bugreportPath, screenshotPath);
-        return acceptBugreportAndGetSharedIntent();
+        return acceptBugreportAndGetSharedIntent(pid);
     }
 
     /**
@@ -513,8 +519,8 @@
      *
      * @return extras sent in the shared intent.
      */
-    private Bundle acceptBugreportAndGetSharedIntent() {
-        acceptBugreport();
+    private Bundle acceptBugreportAndGetSharedIntent(int pid) {
+        acceptBugreport(pid);
         mUiBot.chooseActivity(UI_NAME);
         return mListener.getExtras();
     }
@@ -522,24 +528,24 @@
     /**
      * Waits for the notification to share the finished bugreport.
      */
-    private void waitShareNotification() {
-        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title));
+    private void waitShareNotification(int pid) {
+        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title, pid));
     }
 
     /**
      * Accepts the notification to share the finished bugreport.
      */
-    private void acceptBugreport() {
-        mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title));
+    private void acceptBugreport(int pid) {
+        mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title, pid));
     }
 
     /**
      * Sends a "bugreport finished" intent.
      */
-    private void sendBugreportFinished(Integer pid, String bugreportPath, String screenshotPath) {
+    private void sendBugreportFinished(int pid, String bugreportPath, String screenshotPath) {
         Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
         intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-        if (pid != null) {
+        if (pid != NO_PID) {
             intent.putExtra(EXTRA_PID, pid);
         }
         if (bugreportPath != null) {
@@ -775,7 +781,7 @@
      * Gets the notification button used to take a screenshot.
      */
     private UiObject getScreenshotButton() {
-        openProgressNotification();
+        openProgressNotification(PID);
         return mUiBot.getVisibleObject(
                 mContext.getString(R.string.bugreport_screenshot_action).toUpperCase());
     }
@@ -827,12 +833,15 @@
         /**
          * Gets the UI objects by opening the progress notification and clicking DETAILS.
          */
-        DetailsUi(UiBot uiBot) {
-            openProgressNotification();
+        DetailsUi(UiBot uiBot, int pid) throws UiObjectNotFoundException {
+            openProgressNotification(pid);
             detailsButton = mUiBot.getVisibleObject(
                     mContext.getString(R.string.bugreport_info_action).toUpperCase());
             mUiBot.click(detailsButton, "details_button");
             // TODO: unhardcode resource ids
+            UiObject dialogTitle = mUiBot.getVisibleObjectById("android:id/alertTitle");
+            assertEquals("Wrong title", mContext.getString(R.string.bugreport_info_dialog_title,
+                    pid), dialogTitle.getText().toString());
             nameField = mUiBot.getVisibleObjectById("com.android.shell:id/name");
             titleField = mUiBot.getVisibleObjectById("com.android.shell:id/title");
             descField = mUiBot.getVisibleObjectById("com.android.shell:id/description");
@@ -849,7 +858,7 @@
         }
 
         void reOpen() {
-            openProgressNotification();
+            openProgressNotification(PID);
             mUiBot.click(detailsButton, "details_button");
 
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index c74e411..9e07c6d 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -335,6 +335,7 @@
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
+            android:taskAffinity=""
             android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
             android:resizeable="true"
             android:supportsPictureInPicture="true"
@@ -345,6 +346,7 @@
             android:exported="true"
             android:theme="@style/PipTheme"
             android:launchMode="singleTop"
+            android:taskAffinity=""
             android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
             android:resizeable="true"
             android:supportsPictureInPicture="true"
diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml
index ea4db4b..99121a9 100644
--- a/packages/SystemUI/res/layout/battery_detail.xml
+++ b/packages/SystemUI/res/layout/battery_detail.xml
@@ -14,51 +14,88 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:paddingTop="16dp"
-    android:background="?android:attr/selectableItemBackground"
-    android:clickable="true">
+    android:orientation="vertical">
 
-    <ImageView
-        android:id="@android:id/icon"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:scaleType="fitCenter"
-        android:adjustViewBounds="true"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentStart="true"
+    <TextView
+        android:id="@+id/charge_and_estimation"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="72dp"
+        android:paddingBottom="@dimen/battery_detail_graph_space_top"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textColor="?android:attr/colorAccent" />
+
+    <com.android.settingslib.graph.UsageView
+        android:id="@+id/battery_usage"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
         android:layout_marginStart="16dp"
-        android:layout_marginEnd="32dp" />
+        android:layout_marginEnd="24dp"
+        systemui:sideLabels="@array/battery_labels"
+        android:colorAccent="?android:attr/colorAccent"
+        systemui:textColor="#66FFFFFF" />
 
-    <TextView
-        android:id="@android:id/title"
-        android:layout_width="wrap_content"
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:background="?android:attr/listDivider"
+        android:layout_marginTop="@dimen/battery_detail_graph_space_bottom"
+        android:layout_marginBottom="8dp" />
+
+    <RelativeLayout
+        android:id="@+id/switch_container"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_toStartOf="@android:id/toggle"
-        android:layout_toEndOf="@android:id/icon"
-        android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
-        android:text="@string/battery_detail_switch_title" />
+        android:paddingTop="16dp"
+        android:paddingBottom="16dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:clickable="true">
 
-    <TextView
-        android:id="@android:id/summary"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_below="@android:id/title"
-        android:layout_toStartOf="@android:id/toggle"
-        android:layout_toEndOf="@android:id/icon"
-        android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary"
-        android:text="@string/battery_detail_switch_summary" />
+        <ImageView
+            android:id="@android:id/icon"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:scaleType="fitCenter"
+            android:adjustViewBounds="true"
+            android:layout_alignParentTop="true"
+            android:layout_alignParentStart="true"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="32dp" />
 
-    <Switch
-        android:id="@android:id/toggle"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignParentEnd="true"
-        android:layout_alignParentTop="true"
-        android:layout_marginEnd="16dp"
-        android:clickable="false"
-        android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
+        <TextView
+            android:id="@android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toStartOf="@android:id/toggle"
+            android:layout_toEndOf="@android:id/icon"
+            android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
+            android:text="@string/battery_detail_switch_title" />
 
-</RelativeLayout>
+        <TextView
+            android:id="@android:id/summary"
+            android:visibility="gone"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_toStartOf="@android:id/toggle"
+            android:layout_toEndOf="@android:id/icon"
+            android:textAppearance="@style/TextAppearance.QS.DetailItemSecondary"
+            android:text="@string/battery_detail_switch_summary" />
+
+        <Switch
+            android:id="@android:id/toggle"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginEnd="16dp"
+            android:clickable="false"
+            android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
+
+    </RelativeLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index ddff0f0..bed8f1b 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -14,12 +14,35 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- Extends LinearLayout -->
+<com.android.systemui.qs.QSDetail
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:systemui="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/qs_detail_background"
+    android:paddingBottom="8dp"
+    android:clickable="true"
+    android:visibility="invisible"
+    android:orientation="vertical">
+
+    <include
+        android:id="@+id/qs_detail_header"
+        layout="@layout/qs_detail_header"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:background="@drawable/qs_detail_background"
-        android:paddingBottom="8dp"
-        android:orientation="vertical">
+        android:layout_height="wrap_content"
+        android:layout_marginTop="28dp"
+        />
+
+    <com.android.systemui.statusbar.AlphaOptimizedImageView
+        android:id="@+id/qs_detail_header_progress"
+        android:src="@drawable/indeterminate_anim"
+        android:alpha="0"
+        android:background="@color/qs_detail_progress_track"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        systemui:hasOverlappingRendering="false"
+        />
 
     <FrameLayout
             android:id="@android:id/content"
@@ -53,4 +76,4 @@
                 android:focusable="true"/>
 
     </LinearLayout>
-</LinearLayout>
+</com.android.systemui.qs.QSDetail>
diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index 153e35f..df46271 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -19,7 +19,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:paddingEnd="@dimen/qs_panel_padding"
-    android:visibility="invisible"
     android:background="@drawable/btn_borderless_rect"
     android:gravity="center">
 
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index 127bddd..c23c745 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -20,11 +20,31 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-    <com.android.systemui.qs.PageIndicator
-        android:id="@+id/page_indicator"
-        android:layout_width="match_parent"
+    <FrameLayout
+        android:id="@+id/page_decor"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal|bottom"
-        android:gravity="center" />
+        android:layout_gravity="bottom">
+
+        <com.android.systemui.qs.PageIndicator
+            android:id="@+id/page_indicator"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:gravity="center" />
+
+        <TextView
+            android:id="@android:id/edit"
+            style="@style/QSBorderlessButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end"
+            android:minWidth="88dp"
+            android:textAppearance="@style/TextAppearance.QS.DetailButton"
+            android:textColor="#4DFFFFFF"
+            android:focusable="true"
+            android:text="@string/qs_edit" />
+
+    </FrameLayout>
 
 </com.android.systemui.qs.PagedTileLayout>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index bb37b83..9f90af2 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -18,13 +18,18 @@
         android:id="@+id/quick_settings_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@drawable/qs_background_primary"
-        android:paddingBottom="8dp"
-        android:elevation="2dp">
+        android:background="@drawable/qs_background_primary">
 
     <com.android.systemui.qs.QSPanel
             android:id="@+id/quick_settings_panel"
             android:background="#0000"
+            android:layout_marginTop="@dimen/status_bar_header_height"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content" />
+            android:layout_height="wrap_content"
+            android:paddingBottom="8dp" />
+
+    <include layout="@layout/quick_status_bar_expanded_header" />
+
+    <include android:id="@+id/qs_detail" layout="@layout/qs_detail" />
+
 </com.android.systemui.qs.QSContainer>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 07ac6a5..26152cd 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -34,19 +34,31 @@
     <LinearLayout
         android:id="@+id/expanded_group"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
+        android:layout_height="48dp"
         android:gravity="center"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:orientation="horizontal"
         android:layout_alignParentEnd="true"
-        android:layout_marginTop="30dp"
-        android:layout_marginEnd="16dp">
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="12dp">
+
+        <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:layout_alignParentEnd="true"
+            android:background="@drawable/ripple_drawable" >
+            <ImageView android:id="@+id/multi_user_avatar"
+                android:layout_width="@dimen/multi_user_avatar_expanded_size"
+                android:layout_height="@dimen/multi_user_avatar_expanded_size"
+                android:layout_gravity="center"
+                android:scaleType="centerInside"/>
+        </com.android.systemui.statusbar.phone.MultiUserSwitch>
 
         <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
             android:id="@+id/settings_button_container"
             android:layout_width="48dp"
-            android:layout_height="@dimen/status_bar_header_height"
+            android:layout_height="48dp"
             android:clipChildren="false"
             android:clipToPadding="false">
 
@@ -68,18 +80,6 @@
 
         </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
 
-        <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:layout_alignParentEnd="true"
-            android:background="@drawable/ripple_drawable" >
-            <ImageView android:id="@+id/multi_user_avatar"
-                android:layout_width="@dimen/multi_user_avatar_expanded_size"
-                android:layout_height="@dimen/multi_user_avatar_expanded_size"
-                android:layout_gravity="center"
-                android:scaleType="centerInside"/>
-        </com.android.systemui.statusbar.phone.MultiUserSwitch>
-
         <ImageView
             android:layout_width="48dp"
             android:layout_height="48dp"
@@ -104,44 +104,62 @@
         android:gravity="center_vertical" />
 
     <LinearLayout
-        android:id="@+id/date_time_group"
+        android:id="@+id/date_time_alarm_group"
         android:layout_width="wrap_content"
-        android:layout_height="25dp"
+        android:layout_height="wrap_content"
         android:layout_alignParentStart="true"
         android:layout_alignParentTop="true"
-        android:orientation="horizontal">
-
-        <include layout="@layout/split_clock_view"
+        android:layout_marginStart="16dp"
+        android:gravity="start"
+        android:orientation="vertical">
+        <LinearLayout
+            android:id="@+id/date_time_group"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="16dp"
+            android:layout_height="19dp"
             android:layout_marginTop="4dp"
-            android:id="@+id/clock" />
+            android:orientation="horizontal">
 
-        <com.android.systemui.statusbar.policy.DateView
-            android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginStart="6dp"
-            android:layout_marginTop="4dp"
-            android:drawableStart="@drawable/header_dot"
-            android:drawablePadding="6dp"
-            android:singleLine="true"
-            android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
-            android:textSize="@dimen/qs_time_collapsed_size"
-            android:gravity="top"
-            systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
+            <include layout="@layout/split_clock_view"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:id="@+id/clock" />
+
+            <com.android.systemui.statusbar.policy.DateView
+                android:id="@+id/date"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="6dp"
+                android:drawableStart="@drawable/header_dot"
+                android:drawablePadding="6dp"
+                android:singleLine="true"
+                android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
+                android:textSize="@dimen/qs_time_collapsed_size"
+                android:gravity="top"
+                systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
+
+            <com.android.systemui.statusbar.AlphaOptimizedButton
+                android:id="@+id/alarm_status_collapsed"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:drawablePadding="6dp"
+                android:drawableStart="@drawable/ic_access_alarms_small"
+                android:textColor="#64ffffff"
+                android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
+                android:paddingStart="6dp"
+                android:gravity="top"
+                android:background="?android:attr/selectableItemBackground"
+                android:visibility="gone" />
+        </LinearLayout>
 
         <com.android.systemui.statusbar.AlphaOptimizedButton
             android:id="@+id/alarm_status"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_marginTop="4dp"
-            android:drawablePadding="6dp"
+            android:layout_height="20dp"
+            android:paddingTop="3dp"
+            android:drawablePadding="8dp"
             android:drawableStart="@drawable/ic_access_alarms_small"
             android:textColor="#64ffffff"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
-            android:paddingStart="6dp"
             android:gravity="top"
             android:background="?android:attr/selectableItemBackground"
             android:visibility="gone" />
@@ -152,21 +170,13 @@
         android:background="#0000"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="25dp"
+        android:layout_marginTop="28dp"
         android:layout_marginStart="12dp"
         android:layout_marginEnd="12dp"
         android:layout_alignParentEnd="true"
         android:clipChildren="false"
         android:clipToPadding="false" />
 
-    <include
-        android:id="@+id/qs_detail_header"
-        layout="@layout/qs_detail_header"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="28dp"
-        />
-
     <com.android.systemui.statusbar.AlphaOptimizedImageView
         android:id="@+id/qs_detail_header_progress"
         android:src="@drawable/indeterminate_anim"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 89abe2d..289b1d9 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -39,32 +39,11 @@
         android:clipToPadding="false"
         android:clipChildren="false">
 
-        <com.android.systemui.statusbar.phone.ObservableScrollView
-            android:id="@+id/scroll_view"
+        <include
+            layout="@layout/qs_panel"
             android:layout_width="@dimen/notification_panel_width"
-            android:layout_height="match_parent"
-            android:layout_gravity="@integer/notification_panel_layout_gravity"
-            android:scrollbars="none"
-            android:overScrollMode="never"
-            android:fillViewport="true">
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical">
-                <include
-                    layout="@layout/qs_panel"
-                    android:layout_marginTop="@dimen/status_bar_header_height_expanded"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content" />
-
-                <!-- A view to reserve space for the collapsed stack -->
-                <!-- Layout height: notification_min_height + bottom_stack_peek_amount -->
-                <View
-                    android:id="@+id/reserve_notification_space"
-                    android:layout_height="@dimen/min_stack_height"
-                    android:layout_width="match_parent" />
-            </LinearLayout>
-        </com.android.systemui.statusbar.phone.ObservableScrollView>
+            android:layout_height="wrap_content"
+            android:layout_gravity="@integer/notification_panel_layout_gravity" />
 
         <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
             android:id="@+id/notification_stack_scroller"
@@ -90,12 +69,6 @@
             layout="@layout/keyguard_bottom_area"
             android:visibility="gone" />
 
-    <ViewStub
-        android:id="@+id/status_bar_header"
-        android:layout_width="@dimen/notification_panel_width"
-        android:layout_height="@dimen/status_bar_header_height"
-        android:layout_gravity="@integer/notification_panel_layout_gravity" />
-
     <com.android.systemui.statusbar.AlphaOptimizedView
         android:id="@+id/qs_navbar_scrim"
         android:layout_height="96dp"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 3a514ad..8d37e74 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skermvaspen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is in veiligmodus gedeaktiveer."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Geskiedenis"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vee uit"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Verdeel horisontaal"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Pas toe"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bevestig instellings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sommige kleurinstellings kan hierdie toestel onbruikbaar maak. Klik OK om hierdie kleurinstellings te bevestig; andersins sal hierdie instellings ná 10 sekondes teruggestel word."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Batterygebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterybespaarder is nie beskikbaar wanneer gelaai word nie"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterybespaarder"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Verminder werkverrigting en agtergronddata"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Kies Sleutelbordknoppie"</string>
     <string name="preview" msgid="9077832302472282938">"Voorskou"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Sleep om teëls by te voeg"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Wysig"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 39a53b3..2b31ece 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ማያ ገጽ መሰካት"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ታሪክ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ጥረግ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"አግድም ክፈል"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"ተግብር"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ቅንብሮችን ያረጋግጡ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"አንዳንድ የቀለም ቅንብሮች ይህን መሣሪያ የማይጠቅም ሊያደርጉት ይችላሉ። እነዚህን የቀለም ቅንብሮች ለማረጋገጥ እሺ የሚለውን ጠቅ ያድርጉ፣ አለበለዚያ እነዚህ ቅንብሮች ከ10 ሰከንዶች በኋላ ዳግም ይጀምራሉ።"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ባትሪ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ኃይል በሚሞላበት ጊዜ ባትሪ ቆጣቢ አይገኝም"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ባትሪ ቆጣቢ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"አፈጻጸምን እና የጀርባ ውሂብን ይቀንሳል"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"የቁልፍ ሰሌዳ አዝራር ይምረጡ"</string>
     <string name="preview" msgid="9077832302472282938">"ቅድመ-እይታ"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ሰቆችን ለማከል ይጎትቱ"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"አርትዕ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 12f6408..1a1fc2b 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -305,6 +305,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"تثبيت الشاشة"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"السجلّ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"محو"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسيم أفقي"</string>
@@ -481,7 +483,8 @@
     <string name="color_apply" msgid="9212602012641034283">"تطبيق"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"تأكيد الإعدادات"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"يمكن أن تتسبب بعض إعدادات الألوان في تعطيل إمكانية استخدام الجهاز. يمكنك النقر على \"موافق\" لتأكيد إعدادات الألوان هذه، وإلا فستتم إعادة تعيين هذه الإعدادات بعد 10 ثوانٍ."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"البطارية (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"وضع توفير شحن البطارية غير متاح أثناء الشحن."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"توفير شحن البطارية"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"لخفض مستوى الأداء وبيانات الخلفية"</string>
@@ -525,4 +528,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"تحديد زر لوحة المفاتيح"</string>
     <string name="preview" msgid="9077832302472282938">"معاينة"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"اسحب لإضافة مربعات"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"تعديل"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 2cae440..690317f 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sancağı"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"axtarış"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlana bilmir."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> güvənli rejimdə deaktiv edildi."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Tarixçə"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Təmizləyin"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Üfüqi Böl"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Tətbiq edin"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ayarları təsdiq edin"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bəzi renk ayarları bu cihazı yararsız edə bilər. Bu rənk ayarlarını təsdiq etmək üçün OK basın, əks halda bu ayarlar 10 saniyə sonra sıfırlanacaq."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Enerji (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Batareya istifadəsi"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Enerji Qənaəti doldurulma zamanı əlçatan deyil"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Enerji Qənaəti"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı azaldır və arxa fon datasını məhdudlaşdırır"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Klaviatura Düyməsi Seçin"</string>
     <string name="preview" msgid="9077832302472282938">"Önizləmə"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Xanalar əlavə etmək üçün sürüşdürün"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Redaktə edin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6fe4484..3ae995b 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -302,6 +302,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kačenje ekrana"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g> nije uspelo."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podeli horizontalno"</string>
@@ -478,7 +480,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Primeni"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdite podešavanja"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Neka podešavanja boja mogu da učine uređaj neupotrebljivim. Kliknite na Potvrdi da biste potvrdili ova podešavanja boja, pošto će se u suprotnom ova podešavanja resetovati nakon 10 sekundi."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterija (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije nije dostupna tokom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje performanse i pozadinske podatke"</string>
@@ -522,4 +525,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Izaberite dugme za tastaturu"</string>
     <string name="preview" msgid="9077832302472282938">"Pregled"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Prevucite da biste dodali pločice"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Izmeni"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1fa969e..f407ac1 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"фиксиране на екрана"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"История"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Изчистване"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хоризонтално разделяне"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Прилагане"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потвърждаване на настройките"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Някои настройки за цветовете могат да направят това устройство неизползваемо. За да ги потвърдите, кликнете върху „OK“. В противен случай те ще бъдат нулирани след 10 секунди."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батерия (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режимът за запазване на батерията не е налице при зареждане"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим за запазване на батерията"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Намалява ефективността и данните на заден план"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Избиране на клавиш от клавиатурата"</string>
     <string name="preview" msgid="9077832302472282938">"Визуализация"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Преместете с плъзгане, за да добавите плочки"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Редактиране"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 92b7bcc..988e02e 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"স্ক্রীন পিন করা"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> অক্ষম করা হয়েছে৷"</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"ইতিহাস"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"সাফ করুন"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"অনুভূমিক স্প্লিট"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"প্রয়োগ করুন"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"সেটিংস নিশ্চিত করুন"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"কিছু রঙের সেটিংস এই ডিভাইসকে ব্যবহারের অযোগ্য করে দিতে পারে৷ এই রঙের সেটিংস নিশ্চিত করতে ওকে এ ক্লিক করুন, অন্যথায় ১০ সেকেন্ড পরে এই সেটিংস পুনরায় সেট হবে৷"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ব্যাটারি (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"কার্য-সম্পাদনা ও পশ্চাদপট ডেটাকে কমিয়ে দেয়"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"কীবোর্ডের বোতাম নির্বাচন করুন"</string>
     <string name="preview" msgid="9077832302472282938">"পূর্বরূপ দেখুন"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"টাইলগুলি যোগ করার জন্য টেনে আনুন"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"সম্পাদনা করুন"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 10eed98..2be74a0 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -19,947 +19,487 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for app_label (7164937344850004466) -->
-    <skip />
-    <!-- no translation found for status_bar_clear_all_button (7774721344716731603) -->
-    <skip />
-    <!-- no translation found for status_bar_recent_remove_item_title (6026395868129852968) -->
-    <skip />
-    <!-- no translation found for status_bar_recent_inspect_item_title (7793624864528818569) -->
-    <skip />
-    <!-- no translation found for status_bar_no_recent_apps (7374907845131203189) -->
-    <skip />
-    <!-- no translation found for status_bar_accessibility_dismiss_recents (4576076075226540105) -->
-    <skip />
-    <!-- no translation found for status_bar_accessibility_recent_apps (9138535907802238759) -->
-    <!-- no translation found for status_bar_no_notifications_title (4755261167193833213) -->
-    <skip />
-    <!-- no translation found for status_bar_ongoing_events_title (1682504513316879202) -->
-    <skip />
-    <!-- no translation found for status_bar_latest_events_title (6594767438577593172) -->
-    <skip />
-    <!-- no translation found for battery_low_title (6456385927409742437) -->
-    <skip />
-    <!-- no translation found for battery_low_percent_format (2900940511201380775) -->
-    <skip />
-    <!-- no translation found for battery_low_percent_format_saver_started (6859235584035338833) -->
-    <skip />
-    <!-- no translation found for invalid_charger (4549105996740522523) -->
-    <skip />
-    <!-- no translation found for invalid_charger_title (3515740382572798460) -->
-    <skip />
-    <!-- no translation found for invalid_charger_text (5474997287953892710) -->
-    <skip />
-    <!-- no translation found for battery_low_why (4553600287639198111) -->
-    <skip />
-    <!-- no translation found for battery_saver_confirmation_title (5299585433050361634) -->
-    <skip />
-    <!-- no translation found for battery_saver_confirmation_ok (7507968430447930257) -->
-    <skip />
-    <!-- no translation found for battery_saver_start_action (5576697451677486320) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_settings_button (3023889916699270224) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_auto_rotation (3790482541357798421) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_mute_label (554682549917429396) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_auto_brightness_label (511453614962324674) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_notifications (397146176280905137) -->
-    <skip />
-    <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
-    <skip />
-    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (3504292471512317827) -->
-    <skip />
-    <!-- no translation found for status_bar_use_physical_keyboard (7551903084416057810) -->
-    <skip />
-    <!-- no translation found for usb_device_permission_prompt (834698001271562057) -->
-    <skip />
-    <!-- no translation found for usb_accessory_permission_prompt (5171775411178865750) -->
-    <skip />
-    <!-- no translation found for usb_device_confirm_prompt (5161205258635253206) -->
-    <skip />
-    <!-- no translation found for usb_accessory_confirm_prompt (3808984931830229888) -->
-    <skip />
-    <!-- no translation found for usb_accessory_uri_prompt (513450621413733343) -->
-    <skip />
-    <!-- no translation found for title_usb_accessory (4966265263465181372) -->
-    <skip />
-    <!-- no translation found for label_view (6304565553218192990) -->
-    <skip />
-    <!-- no translation found for always_use_device (1450287437017315906) -->
-    <skip />
-    <!-- no translation found for always_use_accessory (1210954576979621596) -->
-    <skip />
-    <!-- no translation found for usb_debugging_title (4513918393387141949) -->
-    <skip />
-    <!-- no translation found for usb_debugging_message (2220143855912376496) -->
-    <skip />
-    <!-- no translation found for usb_debugging_always (303335496705863070) -->
-    <skip />
-    <!-- no translation found for usb_debugging_secondary_user_title (6353808721761220421) -->
-    <skip />
-    <!-- no translation found for usb_debugging_secondary_user_message (8572228137833020196) -->
-    <skip />
-    <!-- no translation found for compat_mode_on (6623839244840638213) -->
-    <skip />
-    <!-- no translation found for compat_mode_off (4434467572461327898) -->
-    <skip />
-    <!-- no translation found for screenshot_saving_ticker (7403652894056693515) -->
-    <skip />
-    <!-- no translation found for screenshot_saving_title (8242282144535555697) -->
-    <skip />
-    <!-- no translation found for screenshot_saving_text (2419718443411738818) -->
-    <skip />
-    <!-- no translation found for screenshot_saved_title (6461865960961414961) -->
-    <skip />
-    <!-- no translation found for screenshot_saved_text (1152839647677558815) -->
-    <skip />
-    <!-- no translation found for screenshot_failed_title (705781116746922771) -->
-    <skip />
-    <!-- no translation found for screenshot_failed_text (1260203058661337274) -->
-    <skip />
-    <!-- no translation found for usb_preference_title (6551050377388882787) -->
-    <skip />
-    <!-- no translation found for use_mtp_button_title (4333504413563023626) -->
-    <skip />
-    <!-- no translation found for use_ptp_button_title (7517127540301625751) -->
-    <skip />
-    <!-- no translation found for installer_cd_button_title (2312667578562201583) -->
-    <skip />
-    <!-- no translation found for accessibility_back (567011538994429120) -->
-    <skip />
-    <!-- no translation found for accessibility_home (8217216074895377641) -->
-    <skip />
-    <!-- no translation found for accessibility_menu (316839303324695949) -->
-    <skip />
-    <!-- no translation found for accessibility_recent (5208608566793607626) -->
-    <skip />
-    <!-- no translation found for accessibility_search_light (1103867596330271848) -->
-    <skip />
-    <!-- no translation found for accessibility_camera_button (8064671582820358152) -->
-    <skip />
-    <!-- no translation found for accessibility_phone_button (6738112589538563574) -->
-    <skip />
-    <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
-    <skip />
-    <!-- no translation found for accessibility_unlock_button (128158454631118828) -->
-    <skip />
-    <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) -->
-    <skip />
-    <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) -->
-    <skip />
-    <!-- no translation found for unlock_label (8779712358041029439) -->
-    <skip />
-    <!-- no translation found for phone_label (2320074140205331708) -->
-    <skip />
-    <!-- no translation found for voice_assist_label (3956854378310019854) -->
-    <skip />
-    <!-- no translation found for camera_label (7261107956054836961) -->
-    <skip />
-    <!-- no translation found for recents_caption_resize (3517056471774958200) -->
-    <skip />
-    <!-- no translation found for cancel (6442560571259935130) -->
-    <skip />
-    <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
-    <skip />
-    <!-- no translation found for accessibility_compatibility_zoom_example (4220687294564945780) -->
-    <skip />
-    <!-- no translation found for accessibility_bluetooth_connected (2707027633242983370) -->
-    <skip />
-    <!-- no translation found for accessibility_bluetooth_disconnected (7416648669976870175) -->
-    <skip />
-    <!-- no translation found for accessibility_no_battery (358343022352820946) -->
-    <skip />
-    <!-- no translation found for accessibility_battery_one_bar (7774887721891057523) -->
-    <skip />
-    <!-- no translation found for accessibility_battery_two_bars (8500650438735009973) -->
-    <skip />
-    <!-- no translation found for accessibility_battery_three_bars (2302983330865040446) -->
-    <skip />
-    <!-- no translation found for accessibility_battery_full (8909122401720158582) -->
-    <skip />
-    <!-- no translation found for accessibility_no_phone (4894708937052611281) -->
-    <skip />
-    <!-- no translation found for accessibility_phone_one_bar (687699278132664115) -->
-    <skip />
-    <!-- no translation found for accessibility_phone_two_bars (8384905382804815201) -->
-    <skip />
-    <!-- no translation found for accessibility_phone_three_bars (8521904843919971885) -->
-    <skip />
-    <!-- no translation found for accessibility_phone_signal_full (6471834868580757898) -->
-    <skip />
-    <!-- no translation found for accessibility_no_data (4791966295096867555) -->
-    <skip />
-    <!-- no translation found for accessibility_data_one_bar (1415625833238273628) -->
-    <skip />
-    <!-- no translation found for accessibility_data_two_bars (6166018492360432091) -->
-    <skip />
-    <!-- no translation found for accessibility_data_three_bars (9167670452395038520) -->
-    <skip />
-    <!-- no translation found for accessibility_data_signal_full (2708384608124519369) -->
-    <skip />
-    <!-- no translation found for accessibility_wifi_name (7202151365171148501) -->
-    <skip />
-    <!-- no translation found for accessibility_bluetooth_name (8441517146585531676) -->
-    <skip />
-    <!-- no translation found for accessibility_no_wimax (4329180129727630368) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_one_bar (4170994299011863648) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_two_bars (9176236858336502288) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_three_bars (6116551636752103927) -->
-    <skip />
-    <!-- no translation found for accessibility_wimax_signal_full (2768089986795579558) -->
-    <skip />
-    <!-- no translation found for accessibility_ethernet_disconnected (5896059303377589469) -->
-    <skip />
-    <!-- no translation found for accessibility_ethernet_connected (2692130313069182636) -->
-    <skip />
-    <!-- no translation found for accessibility_no_signal (7064645320782585167) -->
-    <skip />
-    <!-- no translation found for accessibility_not_connected (6395326276213402883) -->
-    <skip />
-    <!-- no translation found for accessibility_zero_bars (3806060224467027887) -->
-    <skip />
-    <!-- no translation found for accessibility_one_bar (1685730113192081895) -->
-    <skip />
-    <!-- no translation found for accessibility_two_bars (6437363648385206679) -->
-    <skip />
-    <!-- no translation found for accessibility_three_bars (2648241415119396648) -->
-    <skip />
-    <!-- no translation found for accessibility_signal_full (9122922886519676839) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_on (2385254693624345265) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_off (6475508157786853157) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_connected (8366256693719499665) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_connecting (3812924520316280149) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_gprs (1606477224486747751) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_1x (994133468120244018) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_hspa (2032328855462645198) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_3g (8628562305003568260) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_3.5g (8664845609981692001) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_4g (7741000750630089612) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_lte (5413468808637540658) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_cdma (6132648193978823023) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_roaming (5977362333466556094) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_edge (4477457051631979278) -->
-    <skip />
-    <!-- no translation found for accessibility_data_connection_wifi (2324496756590645221) -->
-    <skip />
-    <!-- no translation found for accessibility_no_sim (8274017118472455155) -->
-    <skip />
+    <string name="app_label" msgid="7164937344850004466">"Sistemski UI"</string>
+    <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Obriši"</string>
+    <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Uklanjanje sa spiska"</string>
+    <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Informacije o aplikaciji"</string>
+    <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Ovdje se prikazuju nedavno korišteni ekrani"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Odbaci nedavne aplikacije"</string>
+    <plurals name="status_bar_accessibility_recent_apps" formatted="false" msgid="9138535907802238759">
+      <item quantity="one">%d ekran u Pregledu</item>
+      <item quantity="few">%d ekrana u Pregledu</item>
+      <item quantity="other">%d ekrana u Pregledu</item>
+    </plurals>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nema obavještenja"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"U toku"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Obavještenja"</string>
+    <string name="battery_low_title" msgid="6456385927409742437">"Baterija je skoro prazna"</string>
+    <string name="battery_low_percent_format" msgid="2900940511201380775">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"Preostalo <xliff:g id="PERCENTAGE">%s</xliff:g>. Uključena je štednja baterije."</string>
+    <string name="invalid_charger" msgid="4549105996740522523">"USB punjenje nije podržano.\nKoristite samo priloženi punjač."</string>
+    <string name="invalid_charger_title" msgid="3515740382572798460">"Punjenje pomoću USB-a nije podržano."</string>
+    <string name="invalid_charger_text" msgid="5474997287953892710">"Koristite isključivo priloženi punjač."</string>
+    <string name="battery_low_why" msgid="4553600287639198111">"Postavke"</string>
+    <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"Želite li uključiti štednju baterije?"</string>
+    <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"Uključi"</string>
+    <string name="battery_saver_start_action" msgid="5576697451677486320">"Uključi štednju baterije"</string>
+    <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Postavke"</string>
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Automatsko rotiranje ekrana"</string>
+    <string name="status_bar_settings_mute_label" msgid="554682549917429396">"BEZV."</string>
+    <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"Obavještenja"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Dijeljenje Bluetooth veze"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Postavljanje načina unosa"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fizička tastatura"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup USB uređaju?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Dozvoliti aplikaciji <xliff:g id="APPLICATION">%1$s</xliff:g> pristup USB perifernom uređaju?"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kada je ovaj USB uređaj spojen?"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Otvoriti <xliff:g id="ACTIVITY">%1$s</xliff:g> kada se poveže ovaj USB periferni uređaj?"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Nema instaliranih aplikacija za ovaj USB uređaj. Saznajte više o uređaju na <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="title_usb_accessory" msgid="4966265263465181372">"USB periferni uređaj"</string>
+    <string name="label_view" msgid="6304565553218192990">"Prikaži"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Koristiti kao zadanu opciju za ovaj USB uređaj"</string>
+    <string name="always_use_accessory" msgid="1210954576979621596">"Koristiti kao zadanu opciju za ovaj USB uređaj"</string>
+    <string name="usb_debugging_title" msgid="4513918393387141949">"Omogućiti otklanjanje grešaka preko USB-a?"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"RSA otisak prsta za otključavanje računara je: \n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_always" msgid="303335496705863070">"Uvijek dozvoli sa ovog računara"</string>
+    <string name="usb_debugging_secondary_user_title" msgid="6353808721761220421">"Uklanjanje pogreški putem USB-a nije dozvoljeno"</string>
+    <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Korisnik koji je trenutno prijavljen na uređaju ne može uključiti opciju za otklanjanje grešaka koristeći USB. Da biste koristili ovu funkciju prebacite se na korisnika administratora."</string>
+    <string name="compat_mode_on" msgid="6623839244840638213">"Uvećaj prikaz na ekran"</string>
+    <string name="compat_mode_off" msgid="4434467572461327898">"Razvuci prikaz na ekran"</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Spašavanje snimka ekrana..."</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Spašavanje snimka ekrana..."</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Spašavanje snimka ekrana u toku."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran snimljen."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite za prikaz snimka ekrana."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Došlo je do greške prilikom snimanja ekrana."</string>
+    <string name="screenshot_failed_text" msgid="1260203058661337274">"Ekran se ne može snimiti zbog manjka prostora, ili to ne dopuštaju aplikacija ili vaša organizacija."</string>
+    <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Reproduciranje medijskih sadržaja (MTP)"</string>
+    <string name="use_ptp_button_title" msgid="7517127540301625751">"Priključiti kao kameru (PTP)"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Instalirajte Android File Transfer za Mac"</string>
+    <string name="accessibility_back" msgid="567011538994429120">"Nazad"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Dugme za početnu stranicu"</string>
+    <string name="accessibility_menu" msgid="316839303324695949">"Dugme Meni"</string>
+    <string name="accessibility_recent" msgid="5208608566793607626">"Pregled"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Traži"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
+    <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
+    <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
+    <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključaj"</string>
+    <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Dugme za otključavanje, čeka se na otisak prsta"</string>
+    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključaj bez korištenja otiska prsta"</string>
+    <string name="unlock_label" msgid="8779712358041029439">"otključaj"</string>
+    <string name="phone_label" msgid="2320074140205331708">"otvori telefon"</string>
+    <string name="voice_assist_label" msgid="3956854378310019854">"otvori glasovnu pomoć"</string>
+    <string name="camera_label" msgid="7261107956054836961">"otvori kameru"</string>
+    <string name="recents_caption_resize" msgid="3517056471774958200">"Izaberite novi raspored zadataka"</string>
+    <string name="cancel" msgid="6442560571259935130">"Prekini"</string>
+    <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Dugme za uvećavanje u slučaju nekompatibilnosti."</string>
+    <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Uvećani prikaz manjeg ekrana na većem ekranu."</string>
+    <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth je povezan."</string>
+    <string name="accessibility_bluetooth_disconnected" msgid="7416648669976870175">"Bluetooth je isključen."</string>
+    <string name="accessibility_no_battery" msgid="358343022352820946">"Baterija prazna."</string>
+    <string name="accessibility_battery_one_bar" msgid="7774887721891057523">"Baterija na jednoj crtici."</string>
+    <string name="accessibility_battery_two_bars" msgid="8500650438735009973">"Baterija na dvije crtice."</string>
+    <string name="accessibility_battery_three_bars" msgid="2302983330865040446">"Baterija na tri crtice."</string>
+    <string name="accessibility_battery_full" msgid="8909122401720158582">"Baterija je puna."</string>
+    <string name="accessibility_no_phone" msgid="4894708937052611281">"Nema telefonskog signala."</string>
+    <string name="accessibility_phone_one_bar" msgid="687699278132664115">"Telefonski signal na jednoj crtici."</string>
+    <string name="accessibility_phone_two_bars" msgid="8384905382804815201">"Telefonski signal na dvije crtice."</string>
+    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"Telefonski signal na tri crtice."</string>
+    <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"Telefonski signal pun."</string>
+    <string name="accessibility_no_data" msgid="4791966295096867555">"Nema podataka."</string>
+    <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Prijenos podataka na jednoj crtici."</string>
+    <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Prijenos podataka na dvije crtice."</string>
+    <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Prijenos podataka na tri crtice."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Signal za prijenos podataka pun."</string>
+    <string name="accessibility_wifi_name" msgid="7202151365171148501">"Povezan na <xliff:g id="WIFI">%s</xliff:g>."</string>
+    <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"Povezan na <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
+    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Nema WiMAX signala."</string>
+    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"WiMAX signal na jednoj crtici."</string>
+    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX signal na dvije crtice."</string>
+    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX signal na tri crtice."</string>
+    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX signal pun."</string>
+    <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"Veza sa Ethernetom je prekinuta."</string>
+    <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"Ethernet je spojen."</string>
+    <string name="accessibility_no_signal" msgid="7064645320782585167">"Nema signala."</string>
+    <string name="accessibility_not_connected" msgid="6395326276213402883">"Nije povezano."</string>
+    <string name="accessibility_zero_bars" msgid="3806060224467027887">"Nema crtica."</string>
+    <string name="accessibility_one_bar" msgid="1685730113192081895">"Jedna crtica."</string>
+    <string name="accessibility_two_bars" msgid="6437363648385206679">"Dvije crtice."</string>
+    <string name="accessibility_three_bars" msgid="2648241415119396648">"Tri crtice."</string>
+    <string name="accessibility_signal_full" msgid="9122922886519676839">"Pun signal."</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Uključeno."</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"Isključeno."</string>
+    <string name="accessibility_desc_connected" msgid="8366256693719499665">"Povezano"</string>
+    <string name="accessibility_desc_connecting" msgid="3812924520316280149">"Povezivanje."</string>
+    <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
+    <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
+    <string name="accessibility_data_connection_hspa" msgid="2032328855462645198">"HSPA"</string>
+    <string name="accessibility_data_connection_3g" msgid="8628562305003568260">"3G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"3.5G"</string>
+    <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"4G"</string>
+    <string name="accessibility_data_connection_lte" msgid="5413468808637540658">"LTE"</string>
+    <string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Roming"</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">"Nema SIM kartice."</string>
     <string name="accessibility_cell_data_off" msgid="8000803571751407635">"Mobilni podaci isključeni"</string>
-    <!-- no translation found for accessibility_bluetooth_tether (4102784498140271969) -->
-    <skip />
-    <!-- no translation found for accessibility_airplane_mode (834748999790763092) -->
-    <skip />
-    <!-- no translation found for accessibility_no_sims (3957997018324995781) -->
-    <skip />
-    <!-- no translation found for accessibility_carrier_network_change_mode (4017301580441304305) -->
-    <skip />
-    <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
-    <skip />
-    <!-- no translation found for accessibility_settings_button (799583911231893380) -->
-    <skip />
-    <!-- no translation found for accessibility_notifications_button (4498000369779421892) -->
-    <skip />
-    <!-- no translation found for accessibility_remove_notification (3603099514902182350) -->
-    <skip />
-    <!-- no translation found for accessibility_gps_enabled (3511469499240123019) -->
-    <skip />
-    <!-- no translation found for accessibility_gps_acquiring (8959333351058967158) -->
-    <skip />
-    <!-- no translation found for accessibility_tty_enabled (4613200365379426561) -->
-    <skip />
-    <!-- no translation found for accessibility_ringer_vibrate (666585363364155055) -->
-    <skip />
-    <!-- no translation found for accessibility_ringer_silent (9061243307939135383) -->
-    <skip />
+    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Dijeljenje Bluetooth veze."</string>
+    <string name="accessibility_airplane_mode" msgid="834748999790763092">"Način rada u avionu."</string>
+    <string name="accessibility_no_sims" msgid="3957997018324995781">"Nema SIM kartice."</string>
+    <string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Promjena mreže operatera."</string>
+    <string name="accessibility_battery_level" msgid="7451474187113371965">"Baterija na <xliff:g id="NUMBER">%d</xliff:g> posto."</string>
+    <string name="accessibility_settings_button" msgid="799583911231893380">"Postavke sistema."</string>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"Obavještenja."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ukloniti obavještenje."</string>
+    <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS omogućen."</string>
+    <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Uspostavljanje GPS veze."</string>
+    <string name="accessibility_tty_enabled" msgid="4613200365379426561">"Omogućena opcija TeleTypewriter."</string>
+    <string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Zvuk zvona na vibraciji."</string>
+    <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Zvuk zvona nečujan."</string>
     <!-- no translation found for accessibility_casting (6887382141726543668) -->
     <skip />
-    <!-- no translation found for accessibility_work_mode (2478631941714607225) -->
-    <skip />
-    <!-- no translation found for accessibility_recents_item_will_be_dismissed (395770242498031481) -->
-    <skip />
-    <!-- no translation found for accessibility_recents_item_dismissed (6803574935084867070) -->
-    <skip />
-    <!-- no translation found for accessibility_recents_all_items_dismissed (4464697366179168836) -->
-    <skip />
-    <!-- no translation found for accessibility_recents_item_launched (7616039892382525203) -->
-    <skip />
-    <!-- no translation found for accessibility_recents_task_header (1437183540924535457) -->
-    <skip />
-    <!-- no translation found for accessibility_notification_dismissed (854211387186306927) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_notification_shade (4690274844447504208) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_quick_settings (6186378411582437046) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_lock_screen (5625143713611759164) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_settings (3417884241751434521) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_recent_apps (4876900986661819788) -->
-    <skip />
-    <!-- no translation found for accessibility_desc_close (7479755364962766729) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_user (1104846699869476855) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_wifi (5518210213118181692) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_wifi_changed_off (8716484460897819400) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_wifi_changed_on (6440117170789528622) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_mobile (4876806564086241341) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_battery (1480931583381408972) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_airplane_off (7786329360056634412) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_airplane_on (6406141469157599296) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_airplane_changed_off (66846307818850664) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_airplane_changed_on (8983005603505087728) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_priority_on (1448402297221249355) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_none_on (6882582132662613537) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_alarms_on (9152834845587554157) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_off (2371832603753738581) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_changed_off (898107593453022935) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_dnd_changed_on (4483780856613561039) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_off (2133631372372064339) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_on (7681999166216621838) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_connecting (6953242966685343855) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_connected (4306637793614573659) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_changed_off (2730003763480934529) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_bluetooth_changed_on (8722351798763206577) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_location_off (5119080556976115520) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_location_on (5809937096590102036) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_location_changed_off (8526845571503387376) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_location_changed_on (339403053079338468) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_alarm (3959908972897295660) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_close (3115847794692516306) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_more_time (3659274935356197708) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_less_time (2404728746293515623) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_flashlight_off (4936432000069786988) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_flashlight_on (2003479320007841077) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_flashlight_changed_off (3303701786768224304) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_flashlight_changed_on (6531793301533894686) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_color_inversion_changed_off (4406577213290173911) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_color_inversion_changed_on (6897462320184911126) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_hotspot_changed_off (5004708003447561394) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_hotspot_changed_on (2890951609226476206) -->
-    <skip />
-    <!-- no translation found for accessibility_casting_turned_off (1430668982271976172) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_work_mode_off (7045417396436552890) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_work_mode_on (7650588553988014341) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_work_mode_changed_off (5605534876107300711) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_work_mode_changed_on (249840330756998612) -->
-    <skip />
-    <!-- no translation found for accessibility_brightness (8003681285547803095) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog_3g_title (5281770593459841889) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog_4g_title (1601769736881078016) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog_mobile_title (4651001290947318931) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog_title (3932437232199671967) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog (8453242888903772524) -->
-    <skip />
-    <!-- no translation found for data_usage_disabled_dialog_enable (1412395410306390593) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_signal_meter_disconnected (1940231521274147771) -->
-    <skip />
-    <!-- no translation found for status_bar_settings_signal_meter_wifi_nossid (6557486452774597820) -->
-    <skip />
-    <!-- no translation found for gps_notification_searching_text (8574247005642736060) -->
-    <skip />
-    <!-- no translation found for gps_notification_found_text (4619274244146446464) -->
-    <skip />
-    <!-- no translation found for accessibility_location_active (2427290146138169014) -->
-    <skip />
-    <!-- no translation found for accessibility_clear_all (5235938559247164925) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
-    <skip />
-    <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_off (4062780228931590069) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_on_landscape (6731197337665366273) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_off_changed (8134601071026305153) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_on_landscape_changed (3135965553707519743) -->
-    <skip />
-    <!-- no translation found for accessibility_rotation_lock_on_portrait_changed (8922481981834012126) -->
-    <skip />
-    <!-- no translation found for dessert_case (1295161776223959221) -->
-    <skip />
-    <!-- no translation found for start_dreams (7219575858348719790) -->
-    <skip />
-    <!-- no translation found for ethernet_label (7967563676324087464) -->
-    <skip />
-    <!-- no translation found for quick_settings_dnd_label (8735855737575028208) -->
-    <skip />
-    <!-- no translation found for quick_settings_dnd_priority_label (483232950670692036) -->
-    <skip />
-    <!-- no translation found for quick_settings_dnd_alarms_label (2559229444312445858) -->
-    <skip />
-    <!-- no translation found for quick_settings_dnd_none_label (5025477807123029478) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_label (6304190285170721401) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_multiple_devices_label (3912245565613684735) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_off_label (8159652146149219937) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_detail_empty_text (4910015762433302860) -->
-    <skip />
-    <!-- no translation found for quick_settings_brightness_label (6968372297018755815) -->
-    <skip />
-    <!-- no translation found for quick_settings_rotation_unlocked_label (7305323031808150099) -->
-    <skip />
-    <!-- no translation found for quick_settings_rotation_locked_label (6359205706154282377) -->
-    <skip />
-    <!-- no translation found for quick_settings_rotation_locked_portrait_label (5102691921442135053) -->
-    <skip />
-    <!-- no translation found for quick_settings_rotation_locked_landscape_label (8553157770061178719) -->
-    <skip />
-    <!-- no translation found for quick_settings_ime_label (7073463064369468429) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
-    <skip />
-    <!-- no translation found for quick_settings_location_off_label (7464544086507331459) -->
-    <skip />
-    <!-- no translation found for quick_settings_media_device_label (1302906836372603762) -->
-    <skip />
-    <!-- no translation found for quick_settings_rssi_label (7725671335550695589) -->
-    <skip />
-    <!-- no translation found for quick_settings_rssi_emergency_only (2713774041672886750) -->
-    <skip />
-    <!-- no translation found for quick_settings_settings_label (5326556592578065401) -->
-    <skip />
-    <!-- no translation found for quick_settings_time_label (4635969182239736408) -->
-    <skip />
-    <!-- no translation found for quick_settings_user_label (5238995632130897840) -->
-    <skip />
-    <!-- no translation found for quick_settings_user_title (4467690427642392403) -->
-    <skip />
-    <!-- no translation found for quick_settings_user_new_user (9030521362023479778) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_label (9135344704899546041) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_not_connected (7171904845345573431) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_no_network (2221993077220856376) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_off_label (7558778100843885864) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_detail_empty_text (269990350383909226) -->
-    <skip />
-    <!-- no translation found for quick_settings_cast_title (7709016546426454729) -->
-    <skip />
-    <!-- no translation found for quick_settings_casting (6601710681033353316) -->
-    <skip />
-    <!-- no translation found for quick_settings_cast_device_default_name (5367253104742382945) -->
-    <skip />
-    <!-- no translation found for quick_settings_cast_device_default_description (2484573682378634413) -->
-    <skip />
-    <!-- no translation found for quick_settings_cast_detail_empty_text (311785821261640623) -->
-    <skip />
-    <!-- no translation found for quick_settings_brightness_dialog_title (8599674057673605368) -->
-    <skip />
-    <!-- no translation found for quick_settings_brightness_dialog_auto_brightness_label (5064982743784071218) -->
-    <skip />
-    <!-- no translation found for quick_settings_inversion_label (8790919884718619648) -->
-    <skip />
-    <!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
-    <skip />
-    <!-- no translation found for quick_settings_more_settings (326112621462813682) -->
-    <skip />
-    <!-- no translation found for quick_settings_done (3402999958839153376) -->
-    <skip />
-    <!-- no translation found for quick_settings_connected (1722253542984847487) -->
-    <skip />
-    <!-- no translation found for quick_settings_connecting (47623027419264404) -->
-    <skip />
-    <!-- no translation found for quick_settings_tethering_label (7153452060448575549) -->
-    <skip />
-    <!-- no translation found for quick_settings_hotspot_label (6046917934974004879) -->
-    <skip />
-    <!-- no translation found for quick_settings_notifications_label (4818156442169154523) -->
-    <skip />
-    <!-- no translation found for quick_settings_flashlight_label (2133093497691661546) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_title (8575062783675171695) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_data_usage (1964260360259312002) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_remaining_data (722715415543541249) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_over_limit (967669665390990427) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_data_used (1476810587475761478) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_data_limit (56011158504994128) -->
-    <skip />
-    <!-- no translation found for quick_settings_cellular_detail_data_warning (2440098045692399009) -->
-    <skip />
-    <!-- no translation found for quick_settings_work_mode_label (6244915274350490429) -->
-    <skip />
-    <!-- no translation found for recents_empty_message (8682129509540827999) -->
-    <skip />
-    <!-- no translation found for recents_app_info_button_label (2890317189376000030) -->
-    <skip />
-    <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) -->
-    <skip />
-    <!-- no translation found for recents_search_bar_label (8074997400187836677) -->
-    <skip />
-    <!-- no translation found for recents_launch_error_message (2969287838120550506) -->
+    <string name="accessibility_work_mode" msgid="2478631941714607225">"Poslovni režim"</string>
+    <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbaci aplikaciju <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> uklonjena."</string>
+    <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Sve nedavno korištene aplikacije su odbačene."</string>
+    <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokrećem aplikaciju <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavještenje je uklonjeno."</string>
+    <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Obavještenja sa sjenčenjem."</string>
+    <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Brze postavke."</string>
+    <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Zaključan ekran."</string>
+    <string name="accessibility_desc_settings" msgid="3417884241751434521">"Postavke"</string>
+    <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Pregled."</string>
+    <string name="accessibility_desc_close" msgid="7479755364962766729">"Zatvori"</string>
+    <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Korisnik <xliff:g id="USER">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi je isključen."</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi je uključen."</string>
+    <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Podaci o mobilnoj mreži <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Stanje baterije <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Isključen način rada u avionu."</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Uključen način rada u avionu."</string>
+    <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Način rada u avionu je isključen."</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Način rada u avionu je uključen."</string>
+    <string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"Opcija Ne ometaj je uključena, čut će se samo prioritetna obavještenja."</string>
+    <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"Opcija Ne ometaj je uključena, potpuna tišina."</string>
+    <string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"Opcija Ne ometaj je uključena, čut će se samo alarmi."</string>
+    <string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"Opcija Ne ometaj je isključena."</string>
+    <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Opcija Ne ometaj je isključena."</string>
+    <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Opcija Ne ometaj je uključena."</string>
+    <string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Bluetooth isključen."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Bluetooth uključen."</string>
+    <string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Bluetooth se povezuje."</string>
+    <string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"Bluetooth je povezan."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"Bluetooth je isključen."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"Bluetooth je uključen."</string>
+    <string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"Javljanje lokacije isključeno."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"Javljanje lokacije uključeno."</string>
+    <string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"Javljanje lokacije je isključeno."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"Javljanje lokacije je uključeno."</string>
+    <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm je podešen na <xliff:g id="TIME">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_close" msgid="3115847794692516306">"Zatvori ploču."</string>
+    <string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"Više vremena."</string>
+    <string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"Manje vremena."</string>
+    <string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"Svjetiljka isključena."</string>
+    <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"Svjetiljka uključena."</string>
+    <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"Svjetiljka je isključena."</string>
+    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"Svjetiljka je uključena."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"Inverzija boja je isključena."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"Inverzija boja je uključena."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobilna pristupna tačka je isključena."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobilna pristupna tačka je uključena."</string>
+    <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Prebacivanje ekrana je zaustavljeno."</string>
+    <string name="accessibility_quick_settings_work_mode_off" msgid="7045417396436552890">"Poslovni režim isključen."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Poslovni režim uključen."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Poslovni režim je isključen."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Poslovni režim je uključen."</string>
+    <string name="accessibility_brightness" msgid="8003681285547803095">"Osvjetljenje ekrana"</string>
+    <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G prijenos podataka je pauzirano"</string>
+    <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G prijenos podataka je pauzirano"</string>
+    <string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"Mobilni podaci su pauzirani"</string>
+    <string name="data_usage_disabled_dialog_title" msgid="3932437232199671967">"Prijenos podataka je pauziran"</string>
+    <string name="data_usage_disabled_dialog" msgid="8453242888903772524">"Dostigli ste postavljeno ograničenje prijenosa podataka pa je uređaj zaustavio prijenos podataka za preostali dio ovog ciklusa.\n\nAko nastavite, operater vam može naplatiti dodatne troškove."</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"Nastavi"</string>
+    <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Nema internet veze"</string>
+    <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi veza aktivna"</string>
+    <string name="gps_notification_searching_text" msgid="8574247005642736060">"Traženje GPS signala"</string>
+    <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija utvrđena GPS signalom"</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktiviran je zahtjev za lokaciju"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Uklanjanje svih obavještenja."</string>
+    <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavještenja"</string>
+    <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran će se automatski rotirati."</string>
+    <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran je zaključan u vodoravnom prikazu."</string>
+    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran je zaključan u uspravnom prikazu."</string>
+    <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Ekran će se sada automatski rotirati."</string>
+    <string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Ekran je sada zaključan u vodoravnom položaju."</string>
+    <string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Ekran je sada zaključan u uspravnom položaju."</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Slika sa desertima"</string>
+    <string name="start_dreams" msgid="7219575858348719790">"Sanjarenje"</string>
+    <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
+    <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Ne ometaj"</string>
+    <string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Samo prioritetni prekidi"</string>
+    <string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Samo alarmi"</string>
+    <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Potpuna tišina"</string>
+    <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
+    <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (broj uređaja: <xliff:g id="NUMBER">%d</xliff:g>)"</string>
+    <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth isključen."</string>
+    <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Nema dostupnih uparenih uređaja"</string>
+    <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Osvjetljenje"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Automatsko rotiranje"</string>
+    <string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Rotiranje je zaključano"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Uspravno"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Vodoravno"</string>
+    <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način unosa"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokacija"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Utvrđivanje lokacije isključeno"</string>
+    <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Medijski uređaj"</string>
+    <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Samo pozivi za hitne slučajeve"</string>
+    <string name="quick_settings_settings_label" msgid="5326556592578065401">"Postavke"</string>
+    <string name="quick_settings_time_label" msgid="4635969182239736408">"Vrijeme"</string>
+    <string name="quick_settings_user_label" msgid="5238995632130897840">"Ja"</string>
+    <string name="quick_settings_user_title" msgid="4467690427642392403">"Korisnik"</string>
+    <string name="quick_settings_user_new_user" msgid="9030521362023479778">"Novi korisnik"</string>
+    <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+    <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nije povezano"</string>
+    <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nema mreže"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
+    <string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Nema dostupnih Wi-Fi mreža"</string>
+    <string name="quick_settings_cast_title" msgid="7709016546426454729">"Prebacivanje"</string>
+    <string name="quick_settings_casting" msgid="6601710681033353316">"Prebacivanje"</string>
+    <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
+    <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za prebacivanje"</string>
+    <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nema dostupnih uređaja"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Osvjetljenje"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverzija boja"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način rada za ispravku boje"</string>
+    <string name="quick_settings_more_settings" msgid="326112621462813682">"Više postavki"</string>
+    <string name="quick_settings_done" msgid="3402999958839153376">"Gotovo"</string>
+    <string name="quick_settings_connected" msgid="1722253542984847487">"Povezano"</string>
+    <string name="quick_settings_connecting" msgid="47623027419264404">"Povezivanje..."</string>
+    <string name="quick_settings_tethering_label" msgid="7153452060448575549">"Dijeljenje veze"</string>
+    <string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Pristupna tačka"</string>
+    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"Obavještenja"</string>
+    <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Svjetiljka"</string>
+    <string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Mobilni podaci"</string>
+    <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Korištenje podataka"</string>
+    <string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Preostala količina podataka"</string>
+    <string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Prekoračeno"</string>
+    <string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"Iskorišteno <xliff:g id="DATA_USED">%s</xliff:g>"</string>
+    <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Ograničenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
+    <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Poslovni režim"</string>
+    <string name="recents_empty_message" msgid="8682129509540827999">"Ovdje se pojavljuju nedavno korišteni ekrani"</string>
+    <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string>
+    <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kačenje ekrana"</string>
+    <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraga"</string>
+    <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
     <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historija"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Obriši"</string>
-    <!-- no translation found for recents_multistack_add_stack_dialog_split_horizontal (8848514474543427332) -->
-    <skip />
-    <!-- no translation found for recents_multistack_add_stack_dialog_split_vertical (9075292233696180813) -->
-    <skip />
-    <!-- no translation found for recents_multistack_add_stack_dialog_split_custom (4177837597513701943) -->
-    <skip />
-    <!-- no translation found for expanded_header_battery_charged (5945855970267657951) -->
-    <skip />
-    <!-- no translation found for expanded_header_battery_charging (205623198487189724) -->
-    <skip />
-    <!-- no translation found for expanded_header_battery_charging_with_time (457559884275395376) -->
-    <skip />
-    <!-- no translation found for expanded_header_battery_not_charging (4798147152367049732) -->
-    <skip />
-    <!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
-    <skip />
-    <!-- no translation found for description_target_search (3091587249776033139) -->
-    <skip />
-    <!-- no translation found for description_direction_up (7169032478259485180) -->
-    <skip />
-    <!-- no translation found for description_direction_left (7207478719805562165) -->
-    <skip />
-    <!-- no translation found for zen_priority_introduction (3070506961866919502) -->
-    <skip />
-    <!-- no translation found for zen_priority_customize_button (7948043278226955063) -->
-    <skip />
-    <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) -->
-    <skip />
-    <!-- no translation found for zen_silence_introduction (3137882381093271568) -->
-    <skip />
-    <!-- no translation found for keyguard_more_overflow_text (9195222469041601365) -->
-    <skip />
-    <!-- no translation found for speed_bump_explanation (1288875699658819755) -->
-    <skip />
-    <!-- no translation found for notification_tap_again (8524949573675922138) -->
-    <skip />
-    <!-- no translation found for keyguard_unlock (8043466894212841998) -->
-    <skip />
-    <!-- no translation found for phone_hint (4872890986869209950) -->
-    <skip />
-    <!-- no translation found for voice_hint (8939888732119726665) -->
-    <skip />
-    <!-- no translation found for camera_hint (7939688436797157483) -->
-    <skip />
-    <!-- no translation found for interruption_level_none_with_warning (5114872171614161084) -->
-    <skip />
-    <!-- no translation found for interruption_level_none (6000083681244492992) -->
-    <skip />
-    <!-- no translation found for interruption_level_priority (6426766465363855505) -->
-    <skip />
-    <!-- no translation found for interruption_level_alarms (5226306993448328896) -->
-    <skip />
-    <!-- no translation found for interruption_level_none_twoline (3957581548190765889) -->
-    <skip />
-    <!-- no translation found for interruption_level_priority_twoline (1564715335217164124) -->
-    <skip />
-    <!-- no translation found for interruption_level_alarms_twoline (3266909566410106146) -->
-    <skip />
-    <!-- no translation found for interruption_level_all (1330581184930945764) -->
-    <skip />
-    <!-- no translation found for interruption_level_all_twoline (3719402899156124780) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_charging_time (1757251776872835768) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_charging_time_fast (9018981952053914986) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_charging_time_slowly (955252797961724952) -->
-    <skip />
-    <!-- no translation found for accessibility_multi_user_switch_switcher (7305948938141024937) -->
-    <skip />
-    <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
-    <skip />
-    <!-- no translation found for accessibility_multi_user_switch_inactive (1424081831468083402) -->
-    <skip />
-    <!-- no translation found for accessibility_multi_user_switch_quick_contact (3020367729287990475) -->
-    <skip />
-    <!-- no translation found for user_add_user (5110251524486079492) -->
-    <skip />
-    <!-- no translation found for user_new_user_name (426540612051178753) -->
-    <skip />
-    <!-- no translation found for guest_nickname (8059989128963789678) -->
-    <skip />
-    <!-- no translation found for guest_new_guest (600537543078847803) -->
-    <skip />
-    <!-- no translation found for guest_exit_guest (7187359342030096885) -->
-    <skip />
-    <!-- no translation found for guest_exit_guest_dialog_title (8480693520521766688) -->
-    <skip />
-    <!-- no translation found for guest_exit_guest_dialog_message (4155503224769676625) -->
-    <skip />
-    <!-- no translation found for guest_exit_guest_dialog_remove (7402231963862520531) -->
-    <skip />
-    <!-- no translation found for guest_wipe_session_title (6419439912885956132) -->
-    <skip />
-    <!-- no translation found for guest_wipe_session_message (8476238178270112811) -->
-    <skip />
-    <!-- no translation found for guest_wipe_session_wipe (5065558566939858884) -->
-    <skip />
-    <!-- no translation found for guest_wipe_session_dontwipe (1401113462524894716) -->
-    <skip />
-    <!-- no translation found for guest_notification_title (1585278533840603063) -->
-    <skip />
-    <!-- no translation found for guest_notification_text (335747957734796689) -->
-    <skip />
-    <!-- no translation found for guest_notification_remove_action (8820670703892101990) -->
-    <skip />
-    <!-- no translation found for user_logout_notification_title (1453960926437240727) -->
-    <skip />
-    <!-- no translation found for user_logout_notification_text (3350262809611876284) -->
-    <skip />
-    <!-- no translation found for user_logout_notification_action (1195428991423425062) -->
-    <skip />
-    <!-- no translation found for user_add_user_title (4553596395824132638) -->
-    <!-- no translation found for user_add_user_title (2108112641783146007) -->
-    <skip />
-    <!-- no translation found for user_add_user_message_short (2161624834066214559) -->
-    <!-- no translation found for user_add_user_message_short (1511354412249044381) -->
-    <skip />
-    <!-- no translation found for user_remove_user_title (4681256956076895559) -->
-    <skip />
-    <!-- no translation found for user_remove_user_message (1453218013959498039) -->
-    <skip />
-    <!-- no translation found for user_remove_user_remove (7479275741742178297) -->
-    <skip />
-    <!-- no translation found for battery_saver_notification_title (237918726750955859) -->
-    <skip />
-    <!-- no translation found for battery_saver_notification_text (820318788126672692) -->
-    <skip />
-    <!-- no translation found for battery_saver_notification_action_text (109158658238110382) -->
-    <skip />
-    <!-- no translation found for media_projection_dialog_text (3071431025448218928) -->
-    <skip />
-    <!-- no translation found for media_projection_remember_text (3103510882172746752) -->
-    <skip />
-    <!-- no translation found for clear_all_notifications_text (814192889771462828) -->
-    <skip />
-    <!-- no translation found for media_projection_action_text (8470872969457985954) -->
-    <skip />
-    <!-- no translation found for empty_shade_text (708135716272867002) -->
-    <skip />
-    <!-- no translation found for device_owned_footer (3802752663326030053) -->
-    <skip />
-    <!-- no translation found for profile_owned_footer (8021888108553696069) -->
-    <skip />
-    <!-- no translation found for vpn_footer (2388611096129106812) -->
-    <skip />
-    <!-- no translation found for monitoring_title_device_owned (7121079311903859610) -->
-    <skip />
-    <!-- no translation found for monitoring_title_profile_owned (6790109874733501487) -->
-    <skip />
-    <!-- no translation found for monitoring_title (169206259253048106) -->
-    <skip />
-    <!-- no translation found for disable_vpn (4435534311510272506) -->
-    <skip />
-    <!-- no translation found for disconnect_vpn (1324915059568548655) -->
-    <skip />
-    <!-- no translation found for monitoring_description_device_owned (5780988291898461883) -->
-    <skip />
-    <!-- no translation found for monitoring_description_vpn (4445150119515393526) -->
-    <skip />
-    <!-- no translation found for monitoring_description_vpn_device_owned (3090670777499161246) -->
-    <skip />
-    <!-- no translation found for monitoring_description_vpn_profile_owned (2054949132145039290) -->
-    <skip />
-    <!-- no translation found for legacy_vpn_name (6604123105765737830) -->
-    <skip />
-    <!-- no translation found for monitoring_description_app (6259179342284742878) -->
-    <skip />
-    <!-- no translation found for monitoring_description_app_personal (484599052118316268) -->
-    <skip />
-    <!-- no translation found for monitoring_description_app_work (1754325860918060897) -->
-    <skip />
-    <!-- no translation found for monitoring_description_app_personal_work (4946600443852045903) -->
-    <skip />
-    <!-- no translation found for monitoring_description_vpn_app_device_owned (4970443827043261703) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_trust_disabled (7412534203633528135) -->
-    <skip />
-    <!-- no translation found for hidden_notifications_title (7139628534207443290) -->
-    <skip />
-    <!-- no translation found for hidden_notifications_text (2326409389088668981) -->
-    <skip />
-    <!-- no translation found for hidden_notifications_cancel (3690709735122344913) -->
-    <skip />
-    <!-- no translation found for hidden_notifications_setup (41079514801976810) -->
-    <skip />
-    <!-- no translation found for zen_mode_and_condition (4462471036429759903) -->
-    <skip />
-    <!-- no translation found for volume_zen_end_now (3179845345429841822) -->
-    <skip />
-    <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
-    <skip />
-    <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
-    <skip />
-    <!-- no translation found for screen_pinning_title (3273740381976175811) -->
-    <skip />
-    <!-- no translation found for screen_pinning_description (3577937698406151604) -->
-    <skip />
-    <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
-    <skip />
-    <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
-    <skip />
-    <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
-    <skip />
-    <!-- no translation found for volumeui_prompt_message (918680947433389110) -->
-    <skip />
-    <!-- no translation found for volumeui_prompt_allow (7954396902482228786) -->
-    <skip />
-    <!-- no translation found for volumeui_prompt_deny (5720663643411696731) -->
-    <skip />
-    <!-- no translation found for volumeui_notification_title (4906770126345910955) -->
-    <skip />
-    <!-- no translation found for volumeui_notification_text (1826889705095768656) -->
-    <skip />
-    <!-- no translation found for managed_profile_foreground_toast (5421487114739245972) -->
-    <skip />
-    <!-- no translation found for system_ui_tuner (708224127392452018) -->
-    <skip />
-    <!-- no translation found for show_battery_percentage (5444136600512968798) -->
-    <skip />
-    <!-- no translation found for show_battery_percentage_summary (3215025775576786037) -->
-    <skip />
-    <!-- no translation found for quick_settings (10042998191725428) -->
-    <skip />
-    <!-- no translation found for status_bar (4877645476959324760) -->
-    <skip />
-    <!-- no translation found for overview (4018602013895926956) -->
-    <skip />
-    <!-- no translation found for demo_mode (2389163018533514619) -->
-    <skip />
-    <!-- no translation found for enable_demo_mode (4844205668718636518) -->
-    <skip />
-    <!-- no translation found for show_demo_mode (2018336697782464029) -->
-    <skip />
-    <!-- no translation found for status_bar_ethernet (5044290963549500128) -->
-    <skip />
-    <!-- no translation found for status_bar_alarm (8536256753575881818) -->
-    <skip />
-    <!-- no translation found for status_bar_work (6022553324802866373) -->
-    <skip />
-    <!-- no translation found for status_bar_airplane (7057575501472249002) -->
-    <skip />
-    <!-- no translation found for add_tile (2995389510240786221) -->
-    <skip />
-    <!-- no translation found for broadcast_tile (3894036511763289383) -->
-    <skip />
-    <!-- no translation found for zen_alarm_warning_indef (3482966345578319605) -->
-    <skip />
-    <!-- no translation found for zen_alarm_warning (444533119582244293) -->
-    <skip />
-    <!-- no translation found for alarm_template (3980063409350522735) -->
-    <skip />
-    <!-- no translation found for alarm_template_far (4242179982586714810) -->
-    <skip />
-    <!-- no translation found for accessibility_quick_settings_detail (2579369091672902101) -->
-    <skip />
-    <!-- no translation found for accessibility_status_bar_hotspot (4099381329956402865) -->
-    <skip />
-    <!-- no translation found for accessibility_managed_profile (6613641363112584120) -->
-    <skip />
-    <!-- no translation found for tuner_warning_title (7094689930793031682) -->
-    <skip />
-    <!-- no translation found for tuner_warning (8730648121973575701) -->
-    <skip />
-    <!-- no translation found for tuner_persistent_warning (8597333795565621795) -->
-    <skip />
-    <!-- no translation found for got_it (2239653834387972602) -->
-    <skip />
-    <!-- no translation found for tuner_toast (603429811084428439) -->
-    <skip />
-    <!-- no translation found for remove_from_settings (8389591916603406378) -->
-    <skip />
-    <!-- no translation found for remove_from_settings_prompt (6069085993355887748) -->
-    <skip />
-    <!-- no translation found for activity_not_found (348423244327799974) -->
-    <skip />
-    <!-- no translation found for clock_seconds (7689554147579179507) -->
-    <skip />
-    <!-- no translation found for clock_seconds_desc (6282693067130470675) -->
-    <skip />
-    <!-- no translation found for qs_rearrange (8060918697551068765) -->
-    <skip />
-    <!-- no translation found for show_brightness (6613930842805942519) -->
-    <skip />
+    <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podjela po horizontali"</string>
+    <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Podjela po vertikali"</string>
+    <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Prilagođena podjela"</string>
+    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Napunjeno"</string>
+    <string name="expanded_header_battery_charging" msgid="205623198487189724">"Punjenje"</string>
+    <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Do kraja punjenja preostalo <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
+    <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Ne puni se"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža može \n biti nadzirana"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Traži"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Povucite gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Povucite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="zen_priority_introduction" msgid="3070506961866919502">"Zvukovi i vibracije vas neće uznemiravati, osim alarma, podsjetnika, događaja i pozivalaca koje odredite."</string>
+    <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string>
+    <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, videozapise i igre. I dalje ćete moći obavljati pozive."</string>
+    <string name="zen_silence_introduction" msgid="3137882381093271568">"Ovim se blokiraju SVI zvukovi i vibracije, uključujući alarme, muziku, video zapise i igre."</string>
+    <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
+    <string name="speed_bump_explanation" msgid="1288875699658819755">"Prikaži manje važna obavještenja ispod"</string>
+    <string name="notification_tap_again" msgid="8524949573675922138">"Dodirnite ponovo da otvorite"</string>
+    <string name="keyguard_unlock" msgid="8043466894212841998">"Prevucite prema gore da otključate"</string>
+    <string name="phone_hint" msgid="4872890986869209950">"Prevucite preko ikone da otvorite telefon"</string>
+    <string name="voice_hint" msgid="8939888732119726665">"Prevucite preko ikone za glasovnu pomoć"</string>
+    <string name="camera_hint" msgid="7939688436797157483">"Prevucite od ikone da otvorite kameru"</string>
+    <string name="interruption_level_none_with_warning" msgid="5114872171614161084">"Potpuna tišina. Ovo će utišati i čitače ekrana."</string>
+    <string name="interruption_level_none" msgid="6000083681244492992">"Potpuna tišina"</string>
+    <string name="interruption_level_priority" msgid="6426766465363855505">"Samo prioritetni prekidi"</string>
+    <string name="interruption_level_alarms" msgid="5226306993448328896">"Samo alarmi"</string>
+    <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Potpuna\ntišina"</string>
+    <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Samo\nprioritetni prekidi"</string>
+    <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Samo\nalarmi"</string>
+    <string name="interruption_level_all" msgid="1330581184930945764">"Svi"</string>
+    <string name="interruption_level_all_twoline" msgid="3719402899156124780">"Svi \n"</string>
+    <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (do kraja preostalo <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="9018981952053914986">"Brzo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do pune baterije)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="955252797961724952">"Sporo punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do pune baterije)"</string>
+    <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Zamijeni korisnika"</string>
+    <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Zamijeni korisnika. Trenutni korisnik je <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Trenutni korisnik <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
+    <string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Pokaži profil"</string>
+    <string name="user_add_user" msgid="5110251524486079492">"Dodaj korisnika"</string>
+    <string name="user_new_user_name" msgid="426540612051178753">"Novi korisnik"</string>
+    <string name="guest_nickname" msgid="8059989128963789678">"Gost"</string>
+    <string name="guest_new_guest" msgid="600537543078847803">"Dodaj gosta"</string>
+    <string name="guest_exit_guest" msgid="7187359342030096885">"Ukloni gosta"</string>
+    <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Želite li ukloniti gosta?"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Sve aplikacije i svi podaci iz ove sesije bit će izbrisani."</string>
+    <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Ukloni"</string>
+    <string name="guest_wipe_session_title" msgid="6419439912885956132">"Zdravo! Lijepo je opet vidjeti goste."</string>
+    <string name="guest_wipe_session_message" msgid="8476238178270112811">"Želite li nastaviti sesiju?"</string>
+    <string name="guest_wipe_session_wipe" msgid="5065558566939858884">"Počni ispočetka"</string>
+    <string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"Da, nastavi"</string>
+    <string name="guest_notification_title" msgid="1585278533840603063">"Korisnik koji je gost"</string>
+    <string name="guest_notification_text" msgid="335747957734796689">"Da izbrišete aplikacije i podatke, uklonite gosta"</string>
+    <string name="guest_notification_remove_action" msgid="8820670703892101990">"UKLONI GOSTA"</string>
+    <string name="user_logout_notification_title" msgid="1453960926437240727">"Odjavi korisnika"</string>
+    <string name="user_logout_notification_text" msgid="3350262809611876284">"Odjavi trenutnog korisnika"</string>
+    <string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVI KORISNIKA"</string>
+    <string name="user_add_user_title" msgid="4553596395824132638">"Želite dodati novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba uspostaviti svoj prostor.\n\nSvaki korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
+    <string name="user_remove_user_title" msgid="4681256956076895559">"Zaista želite ukloniti korisnika?"</string>
+    <string name="user_remove_user_message" msgid="1453218013959498039">"Sve aplikacije i podaci ovog korisnika bit će izbrisani."</string>
+    <string name="user_remove_user_remove" msgid="7479275741742178297">"Ukloni"</string>
+    <string name="battery_saver_notification_title" msgid="237918726750955859">"Štednja baterije je uključena"</string>
+    <string name="battery_saver_notification_text" msgid="820318788126672692">"Minimizira rad i prijenos podataka u pozadini"</string>
+    <string name="battery_saver_notification_action_text" msgid="109158658238110382">"Isključi štednju baterije"</string>
+    <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> će početi snimati sve što se prikaže na ekranu."</string>
+    <string name="media_projection_remember_text" msgid="3103510882172746752">"Ne prikazuj opet"</string>
+    <string name="clear_all_notifications_text" msgid="814192889771462828">"Očisti sve"</string>
+    <string name="media_projection_action_text" msgid="8470872969457985954">"Pokreni odmah"</string>
+    <string name="empty_shade_text" msgid="708135716272867002">"Nema obavještenja"</string>
+    <string name="device_owned_footer" msgid="3802752663326030053">"Uređaj može biti nadziran"</string>
+    <string name="profile_owned_footer" msgid="8021888108553696069">"Profil može biti nadziran"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"Mreža može biti nadzirana"</string>
+    <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Praćenje uređaja"</string>
+    <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Praćenje profila"</string>
+    <string name="monitoring_title" msgid="169206259253048106">"Praćenje mreže"</string>
+    <string name="disable_vpn" msgid="4435534311510272506">"Isključi VPN"</string>
+    <string name="disconnect_vpn" msgid="1324915059568548655">"Prekini VPN vezu"</string>
+    <string name="monitoring_description_device_owned" msgid="5780988291898461883">"Vašim uređajem upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti postavke, korporativni pristup, aplikacije, podatke povezane sa vašim uređajem i informacije o lokaciji uređaja, kao i upravljati njima. Za više informacija kontaktirajte svog administratora."</string>
+    <string name="monitoring_description_vpn" msgid="4445150119515393526">"Jednoj aplikaciji ste dali odobrenje da uspostavi VPN vezu.\n\nTa aplikacija može pratiti vašu aktivnost na uređaju i mreži, uključujući e-poštu, aplikacije i web-lokacije."</string>
+    <string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Vašim uređajem upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti postavke, korporativni pristup, aplikacije, podatke povezane sa vašim uređajem i informacije o lokaciji uređaja, kao i upravljati njima.\n\nPovezani ste na VPN, koji može pratiti vašu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nZa više informacija kontaktirajte svog administratora."</string>
+    <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Vašim profilom za posao upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti vašu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nZa više informacija kontaktirajte svog administratora.\n\nPovezani ste i na VPN, koji može pratiti vašu aktivnost na mreži."</string>
+    <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+    <string name="monitoring_description_app" msgid="6259179342284742878">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
+    <string name="monitoring_description_app_personal" msgid="484599052118316268">"Povezani ste sa aplikacijom <xliff:g id="APPLICATION">%1$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži, uključujući e-mailove, aplikacije i web-lokacije."</string>
+    <string name="monitoring_description_app_work" msgid="1754325860918060897">"Profilom za posao upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nZa više informacija kontaktirajte svog administratora."</string>
+    <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"Profilom za posao upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je sa aplikacijom <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, koja može pratiti vašu aktivnost na radnoj mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nPovezani ste i sa aplikacijom <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, koja može pratiti vašu aktivnost na privatnoj mreži."</string>
+    <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Vašim uređajem upravlja <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nVaš administrator može pratiti postavke, korporativni pristup, aplikacije, podatke povezane sa vašim uređajem i informacije o lokaciji uređaja, kao i upravljati njima.\n\nPovezani ste sa aplikacijom <xliff:g id="APPLICATION">%2$s</xliff:g>, koja može pratiti vašu aktivnost na mreži, uključujući e-poštu, aplikacije i web-lokacije.\n\nZa više informacija kontaktirajte svog administratora."</string>
+    <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Uređaj će ostati zaključan dok ga ručno ne otključate"</string>
+    <string name="hidden_notifications_title" msgid="7139628534207443290">"Brže primaj obavještenja"</string>
+    <string name="hidden_notifications_text" msgid="2326409389088668981">"Vidi ih prije otključavanja"</string>
+    <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ne, hvala"</string>
+    <string name="hidden_notifications_setup" msgid="41079514801976810">"Postavi"</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">"Završi sada"</string>
+    <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširi"</string>
+    <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skupi"</string>
+    <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran je prikačen"</string>
+    <string name="screen_pinning_description" msgid="3577937698406151604">"Ovim ekran ostaje prikazan dok ga ne otkačite. Da biste ga otkačili dodirnite i držite Nazad."</string>
+    <string name="screen_pinning_positive" msgid="3783985798366751226">"Jasno mi je"</string>
+    <string name="screen_pinning_negative" msgid="3741602308343880268">"Ne, hvala"</string>
+    <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Želite li sakriti <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Pojavit će se sljedeći put kada opciju uključite u postavkama."</string>
+    <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sakrij"</string>
+    <string name="volumeui_prompt_message" msgid="918680947433389110">"<xliff:g id="APP_NAME">%1$s</xliff:g> želi funkcionirati kao dijaloški okvir za jačinu zvuka."</string>
+    <string name="volumeui_prompt_allow" msgid="7954396902482228786">"Dozvoli"</string>
+    <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> je dijaloški okvir za jačinu zvuka"</string>
+    <string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da vratite original."</string>
+    <string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Koristite svoj profil za posao"</string>
+    <string name="system_ui_tuner" msgid="708224127392452018">"Podešavač za korisničko sučelje sistema"</string>
+    <string name="show_battery_percentage" msgid="5444136600512968798">"Prikaži ugrađeni postotak baterije"</string>
+    <string name="show_battery_percentage_summary" msgid="3215025775576786037">"Prikazuje postotak nivoa baterije unutar ikone na statusnoj traci kada se baterija ne puni"</string>
+    <string name="quick_settings" msgid="10042998191725428">"Brze postavke"</string>
+    <string name="status_bar" msgid="4877645476959324760">"Statusna traka"</string>
+    <string name="overview" msgid="4018602013895926956">"Pregled"</string>
+    <string name="demo_mode" msgid="2389163018533514619">"Način demonstracije"</string>
+    <string name="enable_demo_mode" msgid="4844205668718636518">"Omogući način demonstracije"</string>
+    <string name="show_demo_mode" msgid="2018336697782464029">"Prikaži način demonstracije"</string>
+    <string name="status_bar_ethernet" msgid="5044290963549500128">"Ethernet"</string>
+    <string name="status_bar_alarm" msgid="8536256753575881818">"Alarm"</string>
+    <string name="status_bar_work" msgid="6022553324802866373">"Profil za posao"</string>
+    <string name="status_bar_airplane" msgid="7057575501472249002">"Način rada u avionu"</string>
+    <string name="add_tile" msgid="2995389510240786221">"Dodaj pločicu"</string>
+    <string name="broadcast_tile" msgid="3894036511763289383">"Pločica za informacije"</string>
+    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Nećete čuti sljedeći alarm u <xliff:g id="WHEN">%1$s</xliff:g> ako prije toga ovo ne isključite"</string>
+    <string name="zen_alarm_warning" msgid="444533119582244293">"Nećete čuti sljedeći alarm u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="alarm_template" msgid="3980063409350522735">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="alarm_template_far" msgid="4242179982586714810">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"Brze postavke, <xliff:g id="TITLE">%s</xliff:g>."</string>
+    <string name="accessibility_status_bar_hotspot" msgid="4099381329956402865">"Pristupna tačka"</string>
+    <string name="accessibility_managed_profile" msgid="6613641363112584120">"Profil za posao"</string>
+    <string name="tuner_warning_title" msgid="7094689930793031682">"Zabava za neke, ali ne za sve"</string>
+    <string name="tuner_warning" msgid="8730648121973575701">"Podešavač za korisničko sučelje sistema vam omogućava dodatne načine da podesite i prilagodite Androidovo sučelje. Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
+    <string name="tuner_persistent_warning" msgid="8597333795565621795">"Ove eksperimentalne funkcije se u budućim verzijama mogu mijenjati, kvariti ili nestati. Budite oprezni."</string>
+    <string name="got_it" msgid="2239653834387972602">"Jasno mi je"</string>
+    <string name="tuner_toast" msgid="603429811084428439">"Čestitamo! Podešavač za korisničko sučelje sistema je dodan u Postavke"</string>
+    <string name="remove_from_settings" msgid="8389591916603406378">"Ukloni iz Postavki"</string>
+    <string name="remove_from_settings_prompt" msgid="6069085993355887748">"Želite li ukloniti Podešavač za korisničko sučelje sistema iz Postavki i prestati koristiti sve njegove funkcije?"</string>
+    <string name="activity_not_found" msgid="348423244327799974">"Aplikacija nije instalirana na uređaju"</string>
+    <string name="clock_seconds" msgid="7689554147579179507">"Prikaži sekunde"</string>
+    <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikaži sekunde na statusnoj traci. Može skratiti trajanje baterije."</string>
+    <string name="qs_rearrange" msgid="8060918697551068765">"Preuredi \"Brze postavke\""</string>
+    <string name="show_brightness" msgid="6613930842805942519">"Prikaži osvjetljenje u opciji \"Brze postavke\""</string>
     <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Uključi akcelerator za dijeljenje ekrana prevlačenjem nagore"</string>
     <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"Uključite pokrete prstima da biste ušli u podijeljeni ekran tako što ćete od dugmeta Pregled prevući prstom prema gore"</string>
-    <!-- no translation found for experimental (6198182315536726162) -->
-    <skip />
-    <!-- no translation found for enable_bluetooth_title (5027037706500635269) -->
-    <skip />
-    <!-- no translation found for enable_bluetooth_message (9106595990708985385) -->
-    <skip />
-    <!-- no translation found for enable_bluetooth_confirmation_ok (6258074250948309715) -->
-    <skip />
-    <!-- no translation found for apply_to_topic (3641403489318659666) -->
-    <skip />
-    <!-- no translation found for apply_to_app (363016783939815960) -->
-    <skip />
-    <!-- no translation found for blocked_importance (5198578988978234161) -->
-    <skip />
-    <!-- no translation found for low_importance (4109929986107147930) -->
-    <skip />
-    <!-- no translation found for default_importance (8192107689995742653) -->
-    <skip />
-    <!-- no translation found for high_importance (1527066195614050263) -->
-    <skip />
-    <!-- no translation found for max_importance (5089005872719563894) -->
-    <skip />
-    <!-- no translation found for notification_importance_blocked (2397192642657872872) -->
-    <skip />
-    <!-- no translation found for notification_importance_low (4383563267370859725) -->
-    <skip />
-    <!-- no translation found for notification_importance_default (4926529615920610817) -->
-    <skip />
-    <!-- no translation found for notification_importance_high (3222680136612408223) -->
-    <skip />
-    <!-- no translation found for notification_importance_max (5236987171904756134) -->
-    <skip />
-    <!-- no translation found for notification_more_settings (816306283396553571) -->
-    <skip />
-    <!-- no translation found for notification_done (5279426047273930175) -->
-    <skip />
-    <!-- no translation found for color_matrix_none (2121957926040543148) -->
-    <skip />
-    <!-- no translation found for color_matrix_night (5943817622105307072) -->
-    <skip />
-    <!-- no translation found for color_matrix_custom (3655576492322298713) -->
-    <skip />
+    <string name="experimental" msgid="6198182315536726162">"Eksperimentalno"</string>
+    <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želiti li uključiti Bluetooth?"</string>
+    <string name="enable_bluetooth_message" msgid="9106595990708985385">"Da povežete tastaturu sa tabletom, prvo morate uključiti Bluetooth."</string>
+    <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"Uključi"</string>
+    <string name="apply_to_topic" msgid="3641403489318659666">"Primijeni na obavještenja koja se odnose na temu <xliff:g id="TOPIC_NAME">%1$s</xliff:g>"</string>
+    <string name="apply_to_app" msgid="363016783939815960">"Primijeni na sva obavještenja ove aplikacije"</string>
+    <string name="blocked_importance" msgid="5198578988978234161">"Blokirano"</string>
+    <string name="low_importance" msgid="4109929986107147930">"Mali značaj"</string>
+    <string name="default_importance" msgid="8192107689995742653">"Normalan značaj"</string>
+    <string name="high_importance" msgid="1527066195614050263">"Visok značaj"</string>
+    <string name="max_importance" msgid="5089005872719563894">"Hitan značaj"</string>
+    <string name="notification_importance_blocked" msgid="2397192642657872872">"Nikada ne prikazuj ova obavještenja"</string>
+    <string name="notification_importance_low" msgid="4383563267370859725">"Nečujno pokaži na dnu spiska obavještenja"</string>
+    <string name="notification_importance_default" msgid="4926529615920610817">"Nečujno prikaži ova obavještenja"</string>
+    <string name="notification_importance_high" msgid="3222680136612408223">"Pokaži na vrhu spiska obavještanja uz zvuk"</string>
+    <string name="notification_importance_max" msgid="5236987171904756134">"Kratki prikaz na ekranu uz zvuk"</string>
+    <string name="notification_more_settings" msgid="816306283396553571">"Više postavki"</string>
+    <string name="notification_done" msgid="5279426047273930175">"Gotovo"</string>
+    <string name="color_matrix_none" msgid="2121957926040543148">"Standardne boje"</string>
+    <string name="color_matrix_night" msgid="5943817622105307072">"Boje za noćni rad"</string>
+    <string name="color_matrix_custom" msgid="3655576492322298713">"Prilagođene boje"</string>
     <string name="color_matrix_auto" msgid="4896624757412029265">"Automatski"</string>
-    <!-- no translation found for color_matrix_unknown (2709202104256265107) -->
+    <string name="color_matrix_unknown" msgid="2709202104256265107">"Nepoznate boje"</string>
+    <string name="color_transform" msgid="6985460408079086090">"Izmjena boja"</string>
+    <string name="color_matrix_show_qs" msgid="1763244354399276679">"Prikaži polje \"Brze postavke\""</string>
+    <string name="color_enable_custom" msgid="6729001308217347501">"Uključi prilagođenu transformaciju"</string>
+    <string name="color_apply" msgid="9212602012641034283">"Prihvati"</string>
+    <string name="color_revert_title" msgid="4746666545480534663">"Potvrdi postavke"</string>
+    <string name="color_revert_message" msgid="9116001069397996691">"S nekim postavkama boja ovaj uređaj može biti neupotrebljiv. Kliknite U redu da biste potvrdili ove postavke boja ili sačekajte 10 sekundi da se postavke vrate na početnu vrijednost."</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
     <skip />
-    <!-- no translation found for color_transform (6985460408079086090) -->
-    <skip />
-    <!-- no translation found for color_matrix_show_qs (1763244354399276679) -->
-    <skip />
-    <!-- no translation found for color_enable_custom (6729001308217347501) -->
-    <skip />
-    <!-- no translation found for color_apply (9212602012641034283) -->
-    <skip />
-    <!-- no translation found for color_revert_title (4746666545480534663) -->
-    <skip />
-    <!-- no translation found for color_revert_message (9116001069397996691) -->
-    <skip />
-    <!-- no translation found for battery_panel_title (3476715163685592453) -->
-    <skip />
-    <!-- no translation found for battery_detail_charging_summary (1279095653533044008) -->
-    <skip />
-    <!-- no translation found for battery_detail_switch_title (6285872470260795421) -->
-    <skip />
-    <!-- no translation found for battery_detail_switch_summary (9049111149407626804) -->
-    <skip />
-    <!-- no translation found for keyboard_shortcut_group_system (6472647649616541064) -->
-    <skip />
-    <!-- no translation found for keyboard_shortcut_group_system_home (3054369431319891965) -->
-    <skip />
-    <!-- no translation found for keyboard_shortcut_group_system_recents (3154851905021926744) -->
-    <skip />
-    <!-- no translation found for keyboard_shortcut_group_system_back (2207004531216446378) -->
-    <skip />
-    <!-- no translation found for tuner_full_zen_title (5905081395132280054) -->
-    <skip />
-    <!-- no translation found for tuner_full_zen_summary (6883568374520596402) -->
-    <skip />
-    <!-- no translation found for volume_and_do_not_disturb (3114580364524650941) -->
-    <skip />
-    <!-- no translation found for volume_down_silent (66962568467719591) -->
-    <skip />
-    <!-- no translation found for volume_up_silent (7141255269783588286) -->
-    <skip />
-    <!-- no translation found for battery (7498329822413202973) -->
-    <skip />
-    <!-- no translation found for clock (7416090374234785905) -->
-    <skip />
-    <!-- no translation found for headset (4534219457597457353) -->
-    <skip />
-    <!-- no translation found for accessibility_status_bar_headphones (9156307120060559989) -->
-    <skip />
-    <!-- no translation found for accessibility_status_bar_headset (8666419213072449202) -->
-    <skip />
-    <!-- no translation found for tuner_status_bar_explanation (9032196769944137864) -->
-    <skip />
+    <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ušteda baterije je isključena prilikom punjenja"</string>
+    <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ušteda baterije"</string>
+    <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ograničava rad i prijenos podataka u pozadini"</string>
+    <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Sistem"</string>
+    <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početak"</string>
+    <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string>
+    <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string>
+    <string name="tuner_full_zen_title" msgid="5905081395132280054">"Prikaži režim Ne ometaj u dijalogu za jačinu zvuka."</string>
+    <string name="tuner_full_zen_summary" msgid="6883568374520596402">"Dopusti punu kontrolu režima Ne ometaj u dijalogu za jačinu zvuka."</string>
+    <string name="volume_and_do_not_disturb" msgid="3114580364524650941">"Jačina zvuka i režim Ne ometaj"</string>
+    <string name="volume_down_silent" msgid="66962568467719591">"Aktiviraj režim Ne ometaj kada se zvuk utiša"</string>
+    <string name="volume_up_silent" msgid="7141255269783588286">"Deaktiviraj režim Ne ometaj kada se zvuk pojača"</string>
+    <string name="battery" msgid="7498329822413202973">"Baterija"</string>
+    <string name="clock" msgid="7416090374234785905">"Sat"</string>
+    <string name="headset" msgid="4534219457597457353">"Slušalice s mikrofonom"</string>
+    <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"Slušalice su priključene"</string>
+    <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"Slušalice s mikrofonom su priključene"</string>
+    <string name="tuner_status_bar_explanation" msgid="9032196769944137864">"Uključite ili isključite prikaz ikona na statusnoj traci."</string>
     <string name="data_saver" msgid="5037565123367048522">"Ušteda podataka"</string>
     <string name="accessibility_data_saver_on" msgid="8454111686783887148">"Ušteda podataka je uključena"</string>
     <string name="accessibility_data_saver_off" msgid="8841582529453005337">"Ušteda podataka je isključena"</string>
@@ -973,8 +513,7 @@
     <string name="select_button" msgid="1597989540662710653">"Odaberite dugme koje želite dodati"</string>
     <string name="add_button" msgid="4134946063432258161">"Dodaj dugme"</string>
     <string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
-    <!-- no translation found for reset (2448168080964209908) -->
-    <skip />
+    <string name="reset" msgid="2448168080964209908">"Ponovno pokretanje"</string>
     <string name="no_home_title" msgid="1563808595146071549">"Dugme za početak nije pronađeno."</string>
     <string name="no_home_message" msgid="5408485011659260911">"Dugme za početak je neophodno za navigaciju ovim uređajem. Dodajte dugme za početak prije pohranjivanja."</string>
     <string name="adjust_button_width" msgid="6138616087197632947">"Podesite širinu dugmeta"</string>
@@ -986,4 +525,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Odaberite dugme na tastaturi"</string>
     <string name="preview" msgid="9077832302472282938">"Pregledaj"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Povucite da biste dodali polja"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 8b1e568..55ab02a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixació de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Esborra"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisió horitzontal"</string>
@@ -446,7 +448,7 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Mostra els segons del rellotge a la barra d\'estat. Això pot afectar la durada de la bateria."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Reorganitza Configuració ràpida"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Mostra la brillantor a Configuració ràpida"</string>
-    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Accelerador per activar pantalla dividida en lliscar amunt"</string>
+    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Activa la pantalla dividida en lliscar amunt"</string>
     <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"Activa el gest per entrar al mode de pantalla dividida en lliscar cap amunt des del botó Visió general"</string>
     <string name="experimental" msgid="6198182315536726162">"Experimental"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Vols activar el Bluetooth?"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplica"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirma la configuració"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunes opcions de configuració de color poden deixar el dispositiu inservible. Fes clic a D\'acord per confirmar la configuració de color; en cas contrari, la configuració es restablirà al cap de 10 segons."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"La funció Estalvi de bateria no està disponible durant la càrrega"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Estalvi de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Redueix el rendiment i les dades en segon pla"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selecciona un botó de teclat"</string>
     <string name="preview" msgid="9077832302472282938">"Previsualització"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arrossega per afegir camps"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Edita"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e6f5f0d..a1423cb 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"připnutí obrazovky"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historie"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazat"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vodorovné rozdělení"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Použít"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ověření nastavení"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Některá nastavení barev mohou způsobit, že zařízení nebude použitelné. Kliknutím na OK toto nastavení barev potvrdíte, v opačném případě se nastavení po 10 sekundách resetuje."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterie (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Spořič baterie při nabíjení není k dispozici."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Spořič baterie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omezuje výkon a data na pozadí"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Vyberte klávesu na klávesnici"</string>
     <string name="preview" msgid="9077832302472282938">"Náhled"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Dlaždice přidáte přetažením"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Upravit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 1919842..b509dfa 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"bliv i app"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er deaktiveret i sikker tilstand."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ryd"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Anvend"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekræft indstillingerne"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Nogle farveindstillinger kan medføre, at du ikke kan bruge enheden. Klik på OK for at bekræfte disse farveindstillinger. Ellers nulstilles disse indstillinger efter ti sekunder."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Batteriforbrug"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparefunktionen er ikke tilgængelig under opladning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparefunktion"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reducerer ydeevne og baggrundsdata"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Vælg tastaturknap"</string>
     <string name="preview" msgid="9077832302472282938">"Eksempelvisning"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Træk for at tilføje felter"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Rediger"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index b69ef33..541f03e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Verlauf"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Löschen"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Geteilte Schaltfläche – horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Übernehmen"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Einstellungen bestätigen"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Einige Farbeinstellungen können dazu führen, dass das Gerät nicht mehr genutzt werden kann. Klicke auf \"OK\", um diese Farbeinstellungen zu bestätigen. Anderenfalls werden diese Einstellungen in 10 Sekunden zurückgesetzt."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akku (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Der Energiesparmodus ist beim Aufladen nicht verfügbar."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Energiesparmodus"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduzierung der Leistung und Hintergrunddaten"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Taste auswählen"</string>
     <string name="preview" msgid="9077832302472282938">"Vorschau"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Zum Hinzufügen von Kacheln ziehen"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Bearbeiten"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 31df4da..ca354dc 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"καρφίτσωμα οθόνης"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Ιστορικό"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Εκκαθάριση"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Οριζόντιος διαχωρισμός"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Εφαρμογή"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Επιβεβαίωση ρυθμίσεων"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ορισμένες ρυθμίσεις χρωμάτων μπορεί να μην επιτρέπουν τη χρήση αυτής της συσκευής. Κάντε κλικ στην επιλογή OK για να επιβεβαιώσετε αυτές τις ρυθμίσεις χρωμάτων, διαφορετικά θα γίνει επαναφορά αυτών των ρυθμίσεων μετά από 10 δευτερόλεπτα."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Μπαταρία (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Η εξοικονόμηση μπαταρίας δεν είναι διαθέσιμη κατά τη διάρκεια της φόρτισης"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Εξοικονόμηση μπαταρίας"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Μειώνει την απόδοση και τα δεδομένα παρασκηνίου"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Επιλογή κουμπιού πληκτρολογίου"</string>
     <string name="preview" msgid="9077832302472282938">"Προεπισκόπηση"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Σύρετε για να προσθέσετε πλακίδια"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Επεξεργασία"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 783536f..14f9301 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
@@ -508,7 +509,7 @@
     <string name="menu_ime" msgid="4943221416525250684">"Menu / Keyboard Switcher"</string>
     <string name="select_button" msgid="1597989540662710653">"Select button to add"</string>
     <string name="add_button" msgid="4134946063432258161">"Add button"</string>
-    <string name="save" msgid="2311877285724540644">"Savings"</string>
+    <string name="save" msgid="2311877285724540644">"Save"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
     <string name="no_home_title" msgid="1563808595146071549">"No home button found"</string>
     <string name="no_home_message" msgid="5408485011659260911">"A home button is required to be able to navigate this device. Please add a home button before saving."</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Select Keyboard Button"</string>
     <string name="preview" msgid="9077832302472282938">"Preview"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 783536f..14f9301 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
@@ -508,7 +509,7 @@
     <string name="menu_ime" msgid="4943221416525250684">"Menu / Keyboard Switcher"</string>
     <string name="select_button" msgid="1597989540662710653">"Select button to add"</string>
     <string name="add_button" msgid="4134946063432258161">"Add button"</string>
-    <string name="save" msgid="2311877285724540644">"Savings"</string>
+    <string name="save" msgid="2311877285724540644">"Save"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
     <string name="no_home_title" msgid="1563808595146071549">"No home button found"</string>
     <string name="no_home_message" msgid="5408485011659260911">"A home button is required to be able to navigate this device. Please add a home button before saving."</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Select Keyboard Button"</string>
     <string name="preview" msgid="9077832302472282938">"Preview"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 783536f..14f9301 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Clear"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Apply"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirm Settings"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Some colour settings can make this device unusable. Click OK to confirm these colour settings, otherwise these settings will reset after 10 seconds."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Battery (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Battery usage"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Battery Saver not available during charging"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduces performance and background data"</string>
@@ -508,7 +509,7 @@
     <string name="menu_ime" msgid="4943221416525250684">"Menu / Keyboard Switcher"</string>
     <string name="select_button" msgid="1597989540662710653">"Select button to add"</string>
     <string name="add_button" msgid="4134946063432258161">"Add button"</string>
-    <string name="save" msgid="2311877285724540644">"Savings"</string>
+    <string name="save" msgid="2311877285724540644">"Save"</string>
     <string name="reset" msgid="2448168080964209908">"Reset"</string>
     <string name="no_home_title" msgid="1563808595146071549">"No home button found"</string>
     <string name="no_home_message" msgid="5408485011659260911">"A home button is required to be able to navigate this device. Please add a home button before saving."</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Select Keyboard Button"</string>
     <string name="preview" msgid="9077832302472282938">"Preview"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 47b5038..4031204 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Fijar pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar la configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunas opciones de configuración de color pueden provocar que el dispositivo quede inutilizable. Haz clic en Aceptar para confirmar estos parámetros de color. De lo contrario, la configuración se restablecerá en diez segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no está disponible durante la carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y el uso de datos en segundo plano"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selecciona un botón del teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Vista previa"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arrastra los mosaicos para agregarlos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index ae1c3c8..f531294 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fijación de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"División horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunas opciones de configuración de color pueden hacer que el dispositivo no se pueda utilizar. Haz clic en Aceptar para confirmar esta configuración. Si no lo haces, se restablecerá esta configuración cuando transcurran 10 segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ahorro de batería no disponible mientras se carga el dispositivo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Ahorro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce el rendimiento y las conexiones automáticas"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selecciona un botón de teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Vista previa"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arrastrar para añadir mosaicos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Cambiar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index eae5ea7..a7e34e6 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekraanikuva kinnitamine"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Rakendus <xliff:g id="APP">%s</xliff:g> on turvarežiimis keelatud."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Ajalugu"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kustuta"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horisontaalne poolitamine"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Rakenda"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Seadete kinnitamine"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Mõni värviseade ei saa seadet võib-olla kasutada. Nende värviseadete kinnitamiseks klõpsake OK, muidu lähtestatakse need seaded 10 sekundi pärast."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Aku (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Akukasutus"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akusäästja pole laadimise ajal saadaval"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akusäästja"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vähendab jõudlust ja taustaandmeid"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Klaviatuuri nupu valimine"</string>
     <string name="preview" msgid="9077832302472282938">"Eelvaade"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Lohistage paanide lisamiseks"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Muuda"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index f8ac7f2..dcb8ef9 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pantaila-ainguratzea"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Garbitu"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Banaketa horizontala"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplikatu"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Berretsi ezarpenak"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Baliteke gailua kolore-ezarpen batzuekin ezin erabili izatea. Kolore-ezarpenak berresteko, sakatu Ados. Bestela, hamar segundoren buruan berrezarriko dira ezarpenak."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (%% <xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Bateria-aurrezlea ez dago erabilgarri gailua kargatzen ari denean"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Bateria-aurrezlea"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Errendimendua eta atzeko planoko datuen erabilera murrizten ditu"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Hautatu teklatuko botoia"</string>
     <string name="preview" msgid="9077832302472282938">"Aurrebista"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arrastatu lauzak hemen gehitzeko"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editatu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 1950221..851a6cb 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"پین کردن صفحه"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"سابقه"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"پاک کردن"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"تقسیم افقی"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"اعمال‌ کردن"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"تأیید تنظیمات"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"بعضی از تنظیمات رنگ می‌توانند این دستگاه را غیرقابل استفاده کنند. برای تأیید این تنظیمات رنگ روی «تأیید» کلیک کنید، در غیر این صورت این تغییرات بعد از ۱۰ ثانیه بازنشانی می‌شوند."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"باتری (<xliff:g id="ID_1">%1$d</xliff:g>٪٪)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"هنگام شارژ شدن، «بهینه‌سازی باتری» در دسترس نیست"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بهینه‌سازی باتری"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"عملکرد و اطلاعات پس‌زمینه را کاهش می‌دهد"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"کلید صفحه‌کلید را انتخاب کنید"</string>
     <string name="preview" msgid="9077832302472282938">"پیش‌نمایش"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"کشیدن برای افزودن کاشی‌ها"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ویرایش"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b3f5425..d44bd75 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"näytön kiinnitys"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tyhjennä"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Vaakasuuntainen jako"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Käytä"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Vahvista asetukset"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Jotkin väriasetukset voivat häiritä laitteen käyttöä. Vahvista uudet väriasetukset valitsemalla OK. Muussa tapauksessa aiemmat asetukset palautetaan 10 sekunnin kuluttua."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akku (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Virransäästö ei ole käytettävissä latauksen aikana."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Virransäästö"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Rajoittaa suorituskykyä ja taustatiedonsiirtoa."</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Valitse näppäimistön näppäin"</string>
     <string name="preview" msgid="9077832302472282938">"Esikatselu"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Lisää osioita vetämällä."</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Muokkaa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 9187aa5..d34723f 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Appliquer"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmer les paramètres"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Certains paramètres de couleurs peuvent rendre cet appareil inutilisable. Cliquez sur « OK » pour valider ces paramètres, sinon ils seront réinitialisés après 10 secondes."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Pile (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Le mode Économie d\'énergie n\'est pas accessible pendant la charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économie d\'énergie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Réduit les performances et les données en arrière-plan"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Sélectionnez la touche du clavier"</string>
     <string name="preview" msgid="9077832302472282938">"Aperçu"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Faites glisser des tuiles ici pour les ajouter"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Modifier"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 767ba86..241d34c 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"épinglage d\'écran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historique"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Effacer"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Séparation horizontale"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Appliquer"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Vérifier les paramètres"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Certains paramètres de couleurs peuvent rendre cet appareil inutilisable. Cliquez sur \"OK\" pour valider ces paramètres, sans quoi ils seront réinitialisés après 10 secondes."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batterie (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"L\'économiseur de batterie n\'est pas disponible lorsque l\'appareil est en charge."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Économiseur de batterie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Limite les performances et les données en arrière-plan."</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Sélectionner la touche du clavier"</string>
     <string name="preview" msgid="9077832302472282938">"Aperçu"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Faites glisser des tuiles ici pour les ajouter"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Modifier"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 24af89b..75e47a5 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixación de pantalla"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historial"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Borrar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dividir en horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configuración"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algunhas opcións de configuración de cor poden facer que este dispositivo sexa inutilizable. Fai clic en Aceptar para confirmar esta configuración de cor; en caso contrario, a configuración restablecerase tras 10 segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batería (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A función aforro de batería non está dispoñible durante a carga"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Aforro de batería"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce o rendemento e os datos en segundo plano"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selecciona o botón do teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Vista previa"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arrastrar para engadir mosaicos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index bb7a9d6..45a4eaf 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"સ્ક્રીન પિનિંગ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"શોધ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી શકાયું નથી."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ઇતિહાસ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"સાફ કરો"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"આડું વિભક્ત કરો"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"લાગુ કરો"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"સેટિંગ્સની પુષ્ટિ કરો"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"કેટલીક રંગ સેટિંગ્સ આ ઉપકરણને બિનઉપયોગી બનાવી શકે છે. આ રંગ સેટિંગ્સની પુષ્ટિ કરવા માટે ઑકે ક્લિક કરો, અન્યથા 10 સેકંડ પછી આ સેટિંગ્સ ફરીથી સેટ થશે."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"બૅટરી (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ચાર્જિંગ દરમિયાન બૅટરી બચતકર્તા ઉપલબ્ધ નથી"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"બૅટરી બચતકર્તા"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"પ્રદર્શન અને પૃષ્ઠભૂમિ ડેટા ઘટાડે છે"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"કીબોર્ડ બટન પસંદ કરો"</string>
     <string name="preview" msgid="9077832302472282938">"પૂર્વાવલોકન કરો"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ટાઇલ્સ ઉમેરવા માટે ખેંચો"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"સંપાદિત કરો"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d6a277d..7349827 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करना"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> को सुरक्षित-मोड में अक्षम किया गया."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ़ करें"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज रूप से विभाजित करें"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू करें"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"से‍ेटिंग की पुष्टि करें"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"कुछ रंग सेटिंग इस डिवाइस को अनुपयोगी बना सकती हैं. इन रंग सेटिंग की पुष्टि करने के लिए ठीक क्लिक करें, अन्यथा 10 सेकंड के बाद ये सेटिंग रीसेट हो जाएंगी."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"बैटरी (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"बैटरी उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज किए जाने के दौरान बैटरी सेवर उपलब्ध नहीं है"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बैटरी सेवर"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"निष्‍पादन और पृष्ठभूमि डेटा को कम करता है"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"कीबोर्ड बटन चुनें"</string>
     <string name="preview" msgid="9077832302472282938">"पूर्वावलोकन"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइलों को जोड़ने के लिए खींचें"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"संपादित करें"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index c9cdd50..06721174 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -302,6 +302,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikvačivanje zaslona"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Povijest"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podijeli vodoravno"</string>
@@ -478,7 +480,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Primijeni"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdite postavke"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Neke postavke boja mogu učiniti uređaj neupotrebljivim. Kliknite U redu da biste potvrdili postavke boja jer će se u suprotnom poništiti za 10 sekundi."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterija (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Potrošnja baterije"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Štednja baterije nije dostupna tijekom punjenja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Štednja baterije"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Smanjuje količinu rada i pozadinske podatke"</string>
@@ -522,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Odaberite gumb tipkovnice"</string>
     <string name="preview" msgid="9077832302472282938">"Pregled"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Povucite da biste dodali pločice"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 8ff4ec9..0dd5d45 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"képernyő rögzítése"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"A(z) <xliff:g id="APP">%s</xliff:g> csökkentett módban ki van kapcsolva."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Előzmények"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Törlés"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Osztott vízszintes"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Alkalmaz"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Beállítások megerősítése"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bizonyos színbeállítások használhatatlanná tehetik ezt az eszközt. A színbeállítás megerősítéséhez kattintson az OK lehetőségre, máskülönben a rendszer 10 másodpercen belül visszaáll a korábbira."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akkumulátor (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Akkumulátorhasználat"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Az Akkumulátorkímélő módot töltés közben nem lehet használni"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akkumulátorkímélő mód"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Csökkenti a teljesítményt és a háttéradatok használatát"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Billentyűgomb kiválasztása"</string>
     <string name="preview" msgid="9077832302472282938">"Előnézet"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Húzza csempe hozzáadásához"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Szerkesztés"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 35f2fb6..4f4af55 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"էկրանի ամրակցում"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Պատմություն"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Մաքրել"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Հորիզոնական տրոհում"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Կիրառել"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Հաստատել կարգավորումները"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Գունային որոշ կարգավորումները կարող են այս սարքը օգտագործման համար ոչ պիտանի դարձնել: Սեղմեք Լավ կոճակը՝ գունային այս կարգավորումները հաստատելու համար: Հակառակ դեպքում այս կարգավորումները կվերակայվեն 10 վայրկյան հետո:"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Մարտկոց (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Մարտկոցի տնտեսումը լիցքավորման ժամանակ հասանելի չէ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Մարտկոցի տնտեսում"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Նվազեցնում է ծանրաբեռնվածությունը և ֆոնային տվյալները"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Ընտրեք ստեղնաշարի կոճակը"</string>
     <string name="preview" msgid="9077832302472282938">"Նախադիտում"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Քաշեք՝ սալիկներ ավելացնելու համար"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Փոփոխել"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index ad28e80..fa359ad 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pin ke layar"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Riwayat"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hapus"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Pisahkan Horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Terapkan"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Konfirmasi setelan"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Beberapa setelan warna dapat membuat perangkat ini tidak dapat digunakan. Klik OKE untuk mengonfirmasi setelan warna ini. Jika tidak, setelan ini akan disetel ulang setelah 10 detik."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterai (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penghemat Baterai tidak tersedia selama pengisian daya"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penghemat Baterai"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangi performa dan data latar belakang"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Pilih Tombol Keyboard"</string>
     <string name="preview" msgid="9077832302472282938">"Pratinjau"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Seret untuk menambahkan ubin"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 522a604..2fca674 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skjáfesting"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Ferill"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Hreinsa"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Lárétt skipting"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Nota"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Staðfesta stillingar"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sumar litastillingar kunna að bitna á notagildi tækisins. Veldu „Í lagi“ til að staðfesta þessar litastillingar, að öðrum kosti verða litirnir endurstilltir eftir tíu sekúndur."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Rafhlaða (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Ekki er hægt að nota rafhlöðusparnað meðan á hleðslu stendur"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Rafhlöðusparnaður"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Dregur úr afköstum og bakgrunnsgögnum"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Veldu lyklaborðshnapp"</string>
     <string name="preview" msgid="9077832302472282938">"Forskoðun"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Dragðu til að bæta við reitum"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Breyta"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 7e6e373..c2c05b4 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"blocco su schermo"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Cronologia"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Cancella"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisione in orizzontale"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Applica"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Conferma le impostazioni"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Alcune impostazioni relative ai colori potrebbero rendere inutilizzabile il dispositivo. Fai clic su OK per confermare queste impostazioni; in caso contrario, le impostazioni verranno reimpostate dopo 10 secondi."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batteria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Risparmio energetico non disponibile durante la ricarica"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Risparmio energetico"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Riduce le prestazioni e i dati in background"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Seleziona il tasto della tastiera"</string>
     <string name="preview" msgid="9077832302472282938">"Anteprima"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Trascina per aggiungere i riquadri"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Modifica"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index bdb0429..2601d36 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"הצמדת מסך"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"היסטוריה"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"נקה"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"פיצול אופקי"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"החל"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"אישור הגדרות"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"הגדרות צבע מסוימות עלולות להפוך את המכשיר הזה לבלתי שמיש. לחץ על אישור כדי לאשר את הגדרות הצבע האלה, אחרת הגדרות אלה יתאפסו לאחר 10 שניות."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"סוללה (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"תכונת החיסכון בסוללה אינה זמינה בעת טעינת המכשיר"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"חיסכון בסוללה"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"מפחית את רמת הביצועים ואת נתוני הרקע"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"בחירת לחצן מקלדת"</string>
     <string name="preview" msgid="9077832302472282938">"תצוגה מקדימה"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"גרור כדי להוסיף משבצות"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ערוך"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 55f7ead..27b3854 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"画面固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"履歴"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"消去"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"横に分割"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"適用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"設定の確認"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"一部の色設定を適用すると、この端末を使用できなくなることがあります。この色設定を確認するには、[OK] をクリックしてください。確認しない場合、10 秒後に設定はリセットされます。"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"バッテリー(<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電中はバッテリー セーバーは利用できません"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"バッテリー セーバー"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"パフォーマンスとバックグラウンド データを制限します"</string>
@@ -524,4 +527,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"キーボードのボタンの選択"</string>
     <string name="preview" msgid="9077832302472282938">"プレビュー"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"タイルを追加するにはドラッグしてください"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"編集"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 6a0ece8..dc48079 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ეკრანზე ჩამაგრება"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ისტორია"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"გასუფთავება"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ჰორიზონტალური გაყოფა"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"გამოყენება"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"პარამეტრების დადასტურება"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ფერთა ზოგიერთ პარამეტრს ამ მოწყობილობასთან მუშაობის გართულება შეუძლია. ფერთა ამჟამინდელი პარამეტრების დასადასტურებლად, დააწკაპუნეთ „კარგი“-ზე. წინააღმდეგ შემთხვევაში, პარამეტრები 10 წამის შემდეგ ჩამოიყრება."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ბატარეა (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ბატარეის დამზოგი დატენვისას მიწვდომელია"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ბატარეის დამზოგი"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ამცირებს წარმადობას და ფონურ მონაცემებს"</string>
@@ -520,5 +523,6 @@
     <string name="keycode_description" msgid="1403795192716828949">"კლავიშის კოდის ტიპის ღილაკების მეშვეობით ნავიგაციის ზოლში კლავიატურის კლავიშების დამატება არის შესაძლებელი. მათზე დაჭერისას არჩეული კლავიატურის კლავიშის ემულაცია ხდება. პირველ რიგში, ღილაკისთვის უნდა აირჩეს კლავიში, ხოლო შემდეგ სურათი, რომელიც ღილაკზე უნდა იყოს ნაჩვენები."</string>
     <string name="select_keycode" msgid="7413765103381924584">"აირჩიეთ კლავიატურის ღილაკი"</string>
     <string name="preview" msgid="9077832302472282938">"გადახედვა"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"მოზაიკების დასამატებლად, გადაიტანეთ ჩავლებით"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"ფილების დასამატებლად, გადაიტანეთ ჩავლებით"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"რედაქტირება"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 9b50dbc..1268e41 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экранды бекіту"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Тарих"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалау"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Бөлінген көлденең"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Қолдану"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Параметрлерді растау"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Кейбір түс параметрлері бұл құрылғыны пайдалану мүмкін емес етуі мүмкін. Бұл түс параметрлерін растау үшін OK түймесін басыңыз, әйтпесе параметрлер 10 секундтан кейін ысырылады."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Зарядтау кезінде Батарея үнемдегіш қол жетімді емес"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батарея үнемдегіш"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Өнімділікті және фондық деректерді азайтады"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Пернетақта түймесін таңдау"</string>
     <string name="preview" msgid="9077832302472282938">"Алдын ала қарау"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Торлар қосу үшін сүйреңіз"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Өңдеу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index a4d6c06..74b1faf 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ការ​ភ្ជាប់​អេក្រង់"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"មិន​អាច​ចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ប្រវត្តិ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"សម្អាត"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"បំបែកផ្តេក"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"អនុវត្ត"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"បញ្ជាក់ការកំណត់"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ការកំណត់ពណ៌មួយចំនួនអាចធ្វើឲ្យឧបករណ៍នេះមិនអាចប្រើបាន។ សូមចុច យល់ព្រម ដើម្បីបញ្ជាក់ការកំណត់ពណ៌ទាំងនេះ បើមិនដូច្នេះទេការកំណត់ទាំងនេះនឹងកំណត់ឡើងវិញក្នុងរយៈពេល 10 វិនាទីបន្ទាប់។"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ថ្ម (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"កម្មវិធីសន្សំថ្មមិនអាចប្រើបានអំឡុងពេលសាកថ្មទេ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"កម្មវិធីសន្សំថ្ម"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"កាត់បន្ថយប្រតិបត្តិការ និងទិន្នន័យផ្ទៃខាងក្រោយ"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"ជ្រើសប៊ូតុងក្តារចុច"</string>
     <string name="preview" msgid="9077832302472282938">"មើលជាមុន"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"អូសដើម្បីបន្ថែមចំណងជើង"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"កែសម្រួល"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 8c0e42f..5ab6e31 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ಸ್ಕ್ರೀನ್ ಪಿನ್ನಿಂಗ್"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"ಇತಿಹಾಸ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ತೆರವುಗೊಳಿಸು"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ಅಡ್ಡಲಾಗಿ ವಿಭಜಿಸಿದ"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"ಅನ್ವಯಿಸು"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಖಚಿತಪಡಿಸಿ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ಕೆಲವು ಬಣ್ಣ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಈ ಸಾಧನವನ್ನು ಅನುಪಯುಕ್ತಗೊಳಿಸಬಹುದು. ಈ ಬಣ್ಣ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಖಚಿತಪಡಿಸಲು ಸರಿ ಕ್ಲಿಕ್ ಮಾಡಿ, ಇಲ್ಲವಾದರೆ ಈ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು 10 ಸೆಕೆಂಡುಗಳ ನಂತರ ಮರುಹೊಂದಿಸಿ."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ಬ್ಯಾಟರಿ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"ಬ್ಯಾಟರಿ ಬಳಕೆ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ಚಾರ್ಜಿಂಗ್ ಸಮಯದಲ್ಲಿ ಬ್ಯಾಟರಿ ಸೇವರ್‌‌ ಲಭ್ಯವಿರುವುದಿಲ್ಲ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ಬ್ಯಾಟರಿ ಸೇವರ್‌‌"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"ಕೀಬೋರ್ಡ್ ಬಟನ್ ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="preview" msgid="9077832302472282938">"ಪೂರ್ವವೀಕ್ಷಣೆ"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ಟೈಲ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ಸಂಪಾದಿಸು"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 2e0fc90..5e6f65a 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"화면 고정"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"기록"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"삭제"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"수평 분할"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"적용"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"설정 확인"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"일부 색상 설정으로 인해 이 기기를 사용하지 못할 수 있습니다. 확인을 클릭하여 이러한 색상 설정을 확인하지 않으면 10초 후에 설정이 초기화됩니다."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"배터리(<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"충전하는 동안 배터리 세이버는 사용할 수 없습니다."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"배터리 세이버"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"성능 및 백그라운드 데이터를 줄입니다."</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"키보드 버튼 선택"</string>
     <string name="preview" msgid="9077832302472282938">"미리보기"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"드래그하여 타일 추가"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"수정"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 29efca3..7819f40 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"экран кадоо"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Таржымал"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Тазалоо"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Туурасынан бөлүү"</string>
@@ -446,7 +448,7 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Абал тилкесинен сааттын секунддары көрсөтүлсүн. Батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Ыкчам жөндөөлөрдү кайра коюу"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Ыкчам жөндөөлөрдөн жарык деңгээлин көрсөтүү"</string>
-    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Өйдө серпип экранды бөлүүчү ылдамдаткычты иштетүү"</string>
+    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Өйдө серпип экранды бөлгүчтү иштетүү"</string>
     <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"Сереп баскычынан өйдө серпип, экранды бөлүү режимин киргизүү үчүн жаңсоону иштетиңиз"</string>
     <string name="experimental" msgid="6198182315536726162">"Сынамык"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Bluetooth күйгүзүлсүнбү?"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Колдонуу"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Жөндөөлөрдү ырастоо"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Айрым түс жөндөөлөрү бул түзмөктү колдонулгус кылып коюшу мүмкүн. Бул түс жөндөөлөрүн ырастоо үчүн OK баскычын чыкылдатыңыз, болбосо бул жөндөөлөр 10 секунддан кийин баштапкы абалына келтирилет."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Батареяны үнөмдөгүч түзмөк кубатталып жатканда иштебейт"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Батареяны үнөмдөгүч"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Иштин майнаптуулугун начарлатып, фондук дайындарды чектейт"</string>
@@ -520,5 +523,6 @@
     <string name="keycode_description" msgid="1403795192716828949">"Бул баскычтын жардамы менен баскычтоптогу баскычтарды чабыттоо тилкесине кошууга болот. Ал үчүн баскычты жана тийиштүү баскычтын көрүнүшүн тандаңыз."</string>
     <string name="select_keycode" msgid="7413765103381924584">"Баскычтоптогу баскычты тандоо"</string>
     <string name="preview" msgid="9077832302472282938">"Алдын ала көрүү"</string>
-    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Тайлдарды кошуу үчүн сүйрөңүз"</string>
+    <string name="drag_to_add_tiles" msgid="7058945779098711293">"Керектүү нерселерди сүйрөп кошуңуз"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Түзөтүү"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 564adff..622e1e5 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ການ​ປັກ​ໝຸດ​ໜ້າ​ຈໍ​"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່​ສາ​ມາດ​ເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ປະຫວັດ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ລຶບ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ການ​ແຍກ​ລວງ​ຂວາງ"</string>
@@ -447,7 +449,7 @@
     <string name="qs_rearrange" msgid="8060918697551068765">"ຈັດ​ວາງ​ການ​ຕັ້ງ​ຄ່າ​ດ່ວນ​ຄືນ​ໃໝ່"</string>
     <string name="show_brightness" msgid="6613930842805942519">"ສະ​ແດງ​ຄວາມ​ແຈ້ງ​ຢູ່​ໃນ​ການ​ຕັ້ງ​ຄ່າ​ດ່ວນ"</string>
     <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"ເປີດໃຊ້ຕົວເລັ່ງຄວາມໄວການປັດຂຶ້ນຂອງໜ້າຈໍແບບແຍກກັນ"</string>
-    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"ເປີດໃຊ້ທ່າທາງເພື່ອເຂົ້າສູ່ໜ້າຈໍແບບແຍກກັນ ໂດຍການປັດຂຶ້ນຈາກປຸ່ມພາບລວມ"</string>
+    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"ເປີດໃຊ້ທ່າທາງເພື່ອເຂົ້າສູ່ໜ້າຈໍແບບແຍກກັນ ໂດຍການປັດຂຶ້ນຈາກປຸ່ມພາບຮວມ"</string>
     <string name="experimental" msgid="6198182315536726162">"ຍັງຢູ່ໃນການທົດລອງ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ເປີດ​ໃຊ້ Bluetooth ບໍ່?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ເພື່ອ​ເຊື່ອມ​ຕໍ່​ແປ້ນ​ພິມ​ຂອງ​ທ່ານ​ກັບ​ແທັບ​ເລັດ​ຂອງ​ທ່ານ, ກ່ອນ​ອື່ນ​ໝົດ​ທ່ານ​ຕ້ອງ​ເປີດ Bluetooth."</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"ນຳໃຊ້"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ຢືນ​ຢັນ​ການ​ຕັ້ງ​ຄ່າ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ບາງການຕັ້ງຄ່າສີສາມາດເຮັດໃຫ້ອຸປະກອນນີ້ບໍ່ສາມາດໃຊ້ໄດ້. ຄລິກ ຕົກລົງ ເພື່ອຢືນຢັນການຕັ້ງຄ່າສີເຫຼົ່ານີ້, ຖ້າບໍ່ດັ່ງນັ້ນ ການຕັ້ງຄ່າເຫຼົ່ານີ້ຈະຕັ້ງຄືນໃໝ່ ຫຼັງຈາກ 10 ວິນາທີ."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ແບັດເຕີຣີ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ຕົວປະຢັດແບັດເຕີຣີບໍ່ມີໃຫ້ນຳໃຊ້ໃນລະຫວ່າງການສາກ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ຕົວປະຢັດ​ແບັດເຕີຣີ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ຫຼຸດ​ປະ​ສິ​ທິ​ພາບ​ການໃຊ້ງານ ແລະ ​ຂໍ້​ມູນ​ພື້ນຫຼັງ"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"ເລືອກປຸ່ມແປ້ນພິມ"</string>
     <string name="preview" msgid="9077832302472282938">"ສະແດງຕົວຢ່າງ"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ລາກເພື່ອເພີ່ມໄທລ໌"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ແກ້ໄຂ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 085bfdd..34decce7 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekrano prisegimas"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Istorija"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Išvalyti"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontalus skaidymas"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Taikyti"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Nustatymų patvirtinimas"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Dėl kai kurių spalvų nustatymų įrenginys gali būti netinkamas naudoti. Spustelėkite „Gerai“, kad patvirtintumėte šiuos spalvų nustatymus. Kitaip šie nustatymai bus nustatyti iš naujo po 10 sekundžių."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akumuliatorius (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumuliatoriaus tausojimo priemonė nepasiekiama įkraunant"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumuliatoriaus tausojimo priemonė"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sumažinamas našumas ir foninių duomenų naudojimas"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Klaviatūros mygtuko pasirinkimas"</string>
     <string name="preview" msgid="9077832302472282938">"Peržiūrėti"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Nuvilkite, kad pridėtumėte išklotinės elementų"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Redaguoti"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2420b1a..c667f35 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -302,6 +302,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Piespraust ekrānu"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Vēsture"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Notīrīt"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontāls dalījums"</string>
@@ -478,7 +480,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Lietot"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Iestatījumu apstiprināšana"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Noteiktu krāsu iestatījumu dēļ šī ierīce var kļūt nelietojama. Lai apstiprinātu šos krāsu iestatījumus, noklikšķiniet uz Labi. Ja to neizdarīsiet, pēc 10 sekundēm šie iestatījumi tiks atiestatīti."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akumulators (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Akumulatora jaudas taupīšanas režīms uzlādes laikā nav pieejams."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Akumulatora jaudas taupīšanas režīms"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Samazina veiktspēju un fona datus."</string>
@@ -522,4 +525,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Tastatūras pogas atlase"</string>
     <string name="preview" msgid="9077832302472282938">"Priekšskatījums"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Velciet elementus, lai tos pievienotu"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Rediģēt"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 276ae6b..8051ec0 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"прикачување екран"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> е оневозможен во безбеден режим."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Исчисти"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Раздели хоризонтално"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Примени"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потврдете ги поставките"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Некои поставки на боите може да го направат уредот неупотреблив. Кликнете на Во ред за да ги потврдите овие поставки на боите, инаку тие поставки ќе се ресетираат по 10 секунди."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батерија (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Користење батерија"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Штедачот на батерија не е достапен при полнење"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Штедач на батерија"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ја намалува изведбата и податоците во заднина"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Изберете копче за тастатура"</string>
     <string name="preview" msgid="9077832302472282938">"Преглед"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Повлечете за додавање плочки"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Уреди"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index af2576a..4cb8c2e 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"സ്ക്രീൻ പിൻ ചെയ്യൽ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"സുരക്ഷിത മോഡിൽ <xliff:g id="APP">%s</xliff:g> പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"ചരിത്രം"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"മായ്‌ക്കുക"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"ബാധകമാക്കുക"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ക്രമീകരണം സ്ഥിരീകരിക്കുക"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ചില വർണ്ണ ക്രമീകരണത്തിന് ഈ ഉപകരണത്തെ ഉപയോഗരഹിതമാക്കാനാകും. ഈ വർണ്ണ ക്രമീകരണം സ്ഥിരീകരിക്കുന്നതിന് ശരി എന്നതിൽ ക്ലിക്കുചെയ്യുക, അല്ലെങ്കിൽ 10 സെക്കൻഡിന് ശേഷം ഈ ക്രമീകരണം പുനഃക്രമീകരിക്കപ്പെടും."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ബാറ്ററി (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"ബാറ്ററി ഉപയോഗം"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ചാർജുചെയ്യുന്ന സമയത്ത് ബാറ്ററി സേവർ ലഭ്യമല്ല"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ബാറ്ററി സേവർ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"പ്രവർത്തനവും പശ്ചാത്തല ഡാറ്റയും കുറയ്‌ക്കുന്നു"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"കീബോർഡ് ബട്ടൺ തിരഞ്ഞെടുക്കൂ"</string>
     <string name="preview" msgid="9077832302472282938">"പ്രിവ്യു നടത്തുക"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ടൈലുകൾ ചേർക്കുന്നതിന് വലിച്ചിടുക"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"എഡിറ്റുചെയ്യുക"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 2a056fc..f22e315 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -299,6 +299,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"дэлгэц тогтоох"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Түүх"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Устгах"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Хэвтээ чиглэлд хуваах"</string>
@@ -475,7 +477,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Хэрэгжүүлэх"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Тохиргоог баталгаажуулах"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Зарим өнгөний тохиргоо энэ төхөөрөмжийг ашиглах боломжгүй болгож болзошгүй. OK товчлуурыг дарж эдгээр өнгөний тохиргоог зөвшөөрөхгүй бол энэ тохиргоо нь 10 секундын дараа шинэчлэгдэх болно."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Тэжээл (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Цэнэглэх үед тэжээл хэмнэгч ажиллахгүй"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Тэжээл хэмнэгч"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Гүйцэтгэл болон дэвсгэрийн датаг багасгадаг"</string>
@@ -519,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Гарын товчлуур сонгох"</string>
     <string name="preview" msgid="9077832302472282938">"Урьдчилж харах"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Дөрвөлж нэмэхийн тулд чирнэ үү"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Засах"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 4009cc3..ff36be2 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्‍क्रीन पिन करणे"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> सुरक्षित-मोडमध्ये अक्षम केला आहे."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"साफ करा"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"क्षैतिज विभाजित करा"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू करा"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"सेटिंग्जची पुष्टी करा"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"काही रंग सेटिंग्ज या डिव्हाइसला निरुपयोगी करू शकतात. या रंग सेटिंग्जची पुष्टी करण्‍यासाठी ठीक आहे दाबा अन्यथा या सेटिंग्ज 10 सेकंदांनंतर रीसेट होतील."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"बॅटरी (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"बॅटरी वापर"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज करताना बॅटरी बचतकर्ता उपलब्ध नाही"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"बॅटरी बचतकर्ता"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यप्रदर्शन आणि पार्श्वभूमी डेटा कमी करते"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"कीबोर्ड बटण निवडा"</string>
     <string name="preview" msgid="9077832302472282938">"पूर्वावलोकन"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइल जोडण्यासाठी ड्रॅग करा"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"संपादित करा"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 0982186..13a1f00 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"penyematan skrin"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Sejarah"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Kosongkan"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Mendatar Terpisah"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Gunakan"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Sahkan tetapan"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Sesetengah tetapan warna boleh menjadikan peranti ini tidak dapat digunakan. Klik OK untuk mengesahkan tetapan warna ini, jika tidak, tetapan ini akan ditetapkan semula selepas 10 saat."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Penjimat Bateri tidak tersedia semasa mengecas"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Penjimat Bateri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Mengurangkan prestasi dan data latar belakang"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Pilih Butang Papan Kekunci"</string>
     <string name="preview" msgid="9077832302472282938">"Pratonton"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Seret untuk menambahkan jubin"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index bfc2070..60e2812 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"မျက်နှာပြင် ပင်ထိုးမှု"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"မှတ်တမ်း"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ရှင်းလင်းပါ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
@@ -447,7 +449,7 @@
     <string name="qs_rearrange" msgid="8060918697551068765">"အမြန် ဆက်တင်များကို ပြန်စီစဉ်ရန်"</string>
     <string name="show_brightness" msgid="6613930842805942519">"အမြန် ဆက်တင်များထဲက တောက်ပမှုကို ပြရန်"</string>
     <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"မျက်နှာပြင်ခွဲကြည့်ရန် အပေါ်သို့ပွတ်ဆွဲခြင်း လုပ်ဆောင်ချက်ကိုဖွင့်ပါ"</string>
-    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"ခြုံကြည့်သည့်ခလုတ်မှ အပေါ်သို့ပွတ်ဆွဲခြင်းဖြင့် မျက်နှာပြင်ခွဲကြည့်ရန် လက်အမူအယာကိုဖွင့်ပါ"</string>
+    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"ခြုံကြည့်သည့်ခလုတ်မှ အပေါ်သို့ပွတ်ဆွဲခြင်းဖြင့် မျက်နှာပြင်ခွဲကြည့်ရန် လက်ဟန်ကိုဖွင့်ပါ"</string>
     <string name="experimental" msgid="6198182315536726162">"စမ်းသပ်ရေး"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ဘလူးတုသ် ဖွင့်ရမလား။"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"ကီးဘုတ်ကို တပ်ဘလက်နှင့် ချိတ်ဆက်ရန်၊ ပမထဦးစွာ ဘလူးတုသ်ကို ဖွင့်ပါ။"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"အသုံးပြုပါ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ဆက်တင်များကို အတည်ပြုပါ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"အချို့သော အရောင်ဆက်တက်များက ဤကိရိယာကို သုံးမရအောင် လုပ်ပစ်နိုင်ပါသည်။ ဤအရောင် ဆက်တင်များကို အတည်ပြုရန် အိုကေကို နှိပ်ပါ၊ သို့မဟုတ် ဤဆက်တင်များကို ၁၀ စက္ကန့် အကြာတွင် ပြန်ညှိလိုက်ပါမည်။"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ဘက်ထရီ ( <xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"အားသွင်းနေချိန်မှာ Battery Saver ကို သုံးမရပါ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Battery Saver"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"လုပ်ဆောင်မှု နှင့် နောက်ခံ ​ဒေတာကို လျော့နည်းစေပါသည်"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"ကီးဘုတ်ခလုတ်ကို ရွေးချယ်ပါ"</string>
     <string name="preview" msgid="9077832302472282938">"အစမ်းကြည့်ပါ"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"အချပ်များကိုထည့်ရန် ဖိဆွဲပါ"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"တည်းဖြတ်ပါ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3adb0f4..f326a01 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"én-appsmodus"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Logg"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tøm"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Del horisontalt"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Bruk"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekreft innstillingene"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Noen fargeinnstillinger kan gjøre denne enheten ubrukelig. Klikk på OK for å bekrefte disse fargeinnstillingene, ellers blir de tilbakestilt etter ti sekunder."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparing er ikke tilgjengelig under lading"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduserer ytelsen og begrenser bakgrunnsdataene"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Velg tastaturtast"</string>
     <string name="preview" msgid="9077832302472282938">"Forhåndsvisning"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Dra for å legge til fliser"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Endre"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index b26ed6b..9b67d9c 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रिन पिन गर्दै"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"इतिहास"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"मेटाउनुहोस्"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
@@ -447,7 +449,7 @@
     <string name="qs_rearrange" msgid="8060918697551068765">"द्रुत सेटिङहरू पुनः व्यवस्थित गर्नुहोस्"</string>
     <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिङहरूमा उज्यालो देखाउनुहोस्"</string>
     <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"विभाजित-स्क्रिनको स्वाइप-अप एक्सेलेटर सक्रिय गर्नुहोस्"</string>
-    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"परिदृश्य बटनदेखि माथि स्वाइप गरी विभाजित-स्क्रिन प्रविष्ट गर्न गेस्चरलाई सक्रिय गर्नुहोस्"</string>
+    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"परिदृश्य बटनदेखि माथि स्वाइप गरी विभाजित-स्क्रिन प्रविष्ट गर्न इसारालाई सक्रिय गर्नुहोस्"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रयोगात्मक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लुटुथ सक्रिय पार्ने हो?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"आफ्नो ट्याब्लेटसँग किबोर्ड जोड्न, पहिले तपाईँले ब्लुटुथ सक्रिय गर्नुपर्छ।"</string>
@@ -477,7 +479,7 @@
     <string name="color_apply" msgid="9212602012641034283">"लागू गर्नुहोस्"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"सेटिङहरूको पुष्टि गर्नुहोस्"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"केही रङ सेटिङहरूले यस यन्त्रलाई अनुपयोगी बनाउन सक्छन्। यी रङ सेटिङहरू पुष्टि गर्न ठीक छ मा क्लिक गर्नुहोस्, अन्यथा यी सेटिङहरू १० सेकेण्डपछि रिसेट हुनेछन्।"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ब्याट्री (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"ब्याट्रि उपयोग"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"चार्ज गर्ने समयमा ब्याट्री सेभर उपलब्ध छैन"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ब्याट्री सेभर"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"कार्यसम्पादन र पृष्ठभूमि डेटा घटाउँछ"</string>
@@ -521,4 +523,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"किबोर्ड बटन चयन गर्नुहोस्"</string>
     <string name="preview" msgid="9077832302472282938">"पूर्वावलोकन"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"टाइलहरू थप्न तान्नुहोस्"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"सम्पादन गर्नुहोस्"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 947bc0c..23455d8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"scherm vastzetten"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is uitgeschakeld in de veilige modus"</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Geschiedenis"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wissen"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Horizontaal splitsen"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Toepassen"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Instellingen bevestigen"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bij sommige kleurinstellingen kan het apparaat onbruikbaar worden. Klik op OK om deze kleurinstellingen te bevestigen, anders worden deze instellingen na tien seconden gereset."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Accu (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Accugebruik"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Accubesparing niet beschikbaar tijdens opladen"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Accubesparing"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Vermindert de prestaties en achtergrondgegevens"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Toetsenbordknop selecteren"</string>
     <string name="preview" msgid="9077832302472282938">"Voorbeeld"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Sleep om tegels toe te voegen"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Bewerken"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 45bf5b9..0d8ab19 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ਸਕ੍ਰੀਨ ਪਿਨਿੰਗ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ਖੋਜੋ"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਸੁਰੱਖਿਅਤ-ਮੋਡ ਵਿੱਚ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ।"</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"ਇਤਿਹਾਸ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ਸਾਫ਼ ਕਰੋ"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ਹੌਰੀਜ਼ੌਂਟਲ ਸਪਲਿਟ"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"ਲਾਗੂ ਕਰੋ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ਸੈਟਿੰਗਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"ਕੁਝ ਰੰਗ ਸੈਟਿੰਗਾਂ ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਬੇਕਾਰ ਕਰ ਸਕਦੀਆਂ ਹਨ। ਇਹਨਾਂ ਰੰਗ ਸੈਟਿੰਗਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ ਠੀਕ \'ਤੇ ਕਲਿੱਕ ਕਰੋ, ਨਹੀਂ ਤਾਂ ਇਹ ਸੈਟਿੰਗਾਂ 10 ਸਕਿੰਟ ਬਾਅਦ ਮੁੜ-ਸੈੱਟ ਹੋ ਜਾਣਗੀਆਂ।"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"ਬੈਟਰੀ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"ਬੈਟਰੀ ਵਰਤੋਂ"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ਬੈਟਰੀ ਸੇਵਰ ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"ਬੈਟਰੀ ਸੇਵਰ"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ਕਾਰਗੁਜ਼ਾਰੀ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਡੈਟੇ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"ਕੀ-ਬੋਰਡ ਬਟਨ ਚੁਣੋ"</string>
     <string name="preview" msgid="9077832302472282938">"ਝਲਕ"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ਟਾਇਲਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਘਸੀਟੋ"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ਸੰਪਾਦਨ ਕਰੋ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index a709ed5..2eae56a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"przypinanie ekranu"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Wyczyść"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Podziel poziomo"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Zastosuj"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potwierdź ustawienia"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Niektóre ustawienia kolorów mogą utrudniać korzystanie z urządzenia. Kliknij OK, by potwierdzić te ustawienia kolorów. Jeśli tego nie zrobisz, zostaną one zresetowane po 10 sekundach."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Oszczędzanie baterii nie jest dostępne podczas ładowania"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Oszczędzanie baterii"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Zmniejsza wydajność i ogranicza dane w tle"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Wybierz przycisk klawiatury"</string>
     <string name="preview" msgid="9077832302472282938">"Podgląd"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Przeciągnij, aby dodać kafelki"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Edytuj"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 7965242..5219454 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configurações"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas configurações de cor podem tornar o dispositivo inutilizável. Clique em \"OK\" para confirmar essas configurações de cor; caso contrário, essas configurações serão redefinidas após 10 segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Escolha um botão do teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Visualização"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arraste para adicionar blocos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 617e05c..064e565 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação no ecrã"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar as definições"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas definições de cor podem tornar este dispositivo instável. Clique em OK para confirmar estas definições de cor. Caso contrário, estas definições serão repostas após 10 segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Utiliz. da bateria"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Poupança de bateria não disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Poupança de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados de segundo plano"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selecionar o botão do teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Pré-visualizar"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arraste para adicionar mosaicos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 7965242..5219454 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divisão horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicar"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmar configurações"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Algumas configurações de cor podem tornar o dispositivo inutilizável. Clique em \"OK\" para confirmar essas configurações de cor; caso contrário, essas configurações serão redefinidas após 10 segundos."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"A Economia de bateria não fica disponível durante o carregamento"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economia de bateria"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduz o desempenho e os dados em segundo plano"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Escolha um botão do teclado"</string>
     <string name="preview" msgid="9077832302472282938">"Visualização"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Arraste para adicionar blocos"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 26ab25b..1af5b42 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -31,7 +31,7 @@
       <item quantity="one">Un ecran în Recente</item>
     </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nicio notificare"</string>
-    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"În desfăşurare"</string>
+    <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"În desfășurare"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Notificări"</string>
     <string name="battery_low_title" msgid="6456385927409742437">"Bateria este aproape descărcată"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"Procent rămas din baterie: <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
@@ -58,7 +58,7 @@
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Deschideţi <xliff:g id="ACTIVITY">%1$s</xliff:g> la conectarea acestui accesoriu USB?"</string>
     <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"Aplic. instal. nu funcţ. cu acest acces. USB. Aflați despre acest accesoriu la <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"Accesoriu USB"</string>
-    <string name="label_view" msgid="6304565553218192990">"Afişaţi"</string>
+    <string name="label_view" msgid="6304565553218192990">"Afișați"</string>
     <string name="always_use_device" msgid="1450287437017315906">"Utilizaţi în mod prestabilit pt. acest dispoz. USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Utiliz. în mod prestabilit pt. acest accesoriu USB"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Permiteți depanarea USB?"</string>
@@ -302,6 +302,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixare pe ecran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Istoric"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Ștergeți"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Divizare pe orizontală"</string>
@@ -478,7 +480,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Aplicați"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Confirmați setările"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Unele setări pentru culori pot face dispozitivul să nu mai funcționeze. Dați clic pe OK pentru a confirma aceste setări pentru culori. În caz contrar, acestea se vor reseta după 10 secunde."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterie (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Economisirea bateriei nu este disponibilă pe durata încărcării"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Economisirea bateriei"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Reduce performanța și datele de fundal"</string>
@@ -522,4 +525,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Selectați butonul de la tastatură"</string>
     <string name="preview" msgid="9077832302472282938">"Previzualizare"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Trageți pentru a adăuga sectoare"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Editați"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0021827..ba1373f 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Заблокировать в приложении"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Журнал"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистить"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Разделить по горизонтали"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Применить"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Подтвердите настройки"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Некоторые цветовые настройки могут затруднить работу с устройством. Чтобы применить выбранные параметры, нажмите \"ОК\". В противном случае они будут сброшены через 10 секунд."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батарея (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим энергосбережения нельзя включить во время зарядки"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим энергосбережения"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Ограничивает производительность и фоновую передачу данных"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Выберите клавишу"</string>
     <string name="preview" msgid="9077832302472282938">"Просмотр"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Перетащите нужные элементы"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Изменить"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index da6de9c..b15137e 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"තිර ඇමිණීම"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ඉතිහාසය"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"හිස් කරන්න"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"තිරස්ව වෙන් කරන්න"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"යොදන්න"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"සැකසීම් තහවුරු කරන්න"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"සමහර වර්ණ සැකසීම් මෙම උපාංගය භාවිත කළ නොහැකි තත්ත්වයට පත් කළ හැකිය. මෙම වර්ණ සැකසීම් තහවුරු කිරීමට හරි ක්ලික් කරන්න, නැතහොත් මෙම සැකසීම් තත්පර 10කට පසුව යළි සකසනු ඇත."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"බැටරිය (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ආරෝපණය අතරතුර බැටරි සුරැකුම ලබා ගත නොහැකිය."</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"බැටරි සුරැකුම"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ක්‍රියාකාරිත්වය සහ පසුබිම් දත්ත අඩු කරන්න"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"යතුරු පුවරු බොත්තම තෝරන්න"</string>
     <string name="preview" msgid="9077832302472282938">"පෙරදසුන"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ටයිල් එක් කිරීමට අදින්න"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"සංස්කරණය කරන්න"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 62f6b89..199bd90 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripnutie k obrazovke"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"História"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Vymazať"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Rozdeliť vodorovné"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Použiť"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potvrdenie nastavení"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Niektoré nastavenia farieb môžu toto zariadenie znefunkčniť. Tieto nastavenia farieb potvrdíte kliknutím na tlačidlo OK, ináč sa tieto nastavenia o 10 sekúnd obnovia."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batéria (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Počas nabíjania nie je Šetrič batérie k dispozícii"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Šetrič batérie"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Obmedzí výkonnosť a údaje na pozadí"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Výber tlačidla klávesnice"</string>
     <string name="preview" msgid="9077832302472282938">"Ukážka"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Dlaždice pridáte presunutím"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Upraviť"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 7e44fb0..9ebb19d 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -303,6 +303,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripenjanje zaslona"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> je v varnem načinu onemogočena."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Zgodovina"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Razdeli vodoravno"</string>
@@ -448,8 +449,8 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"Prikaže sekunde pri uri v vrstici stanja. To lahko vpliva na čas delovanja pri akumulatorskem napajanju."</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"Preuredi hitre nastavitve"</string>
     <string name="show_brightness" msgid="6613930842805942519">"Prikaz svetlosti v hitrih nastavitvah"</string>
-    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Omogočanje pospeš. za razdeljeni zaslon z vlečenjem navzgor"</string>
-    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"Omogočanje poteze za zagon razdeljenega zaslona, tako da uporabnik od gumba za pregled povleče s prstom navzgor"</string>
+    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"Omogočanje vklopa razdeljenega zaslona z vlečenjem navzgor"</string>
+    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"Omogočanje poteze za vklop razdeljenega zaslona, tako da uporabnik od gumba za pregled povleče s prstom navzgor"</string>
     <string name="experimental" msgid="6198182315536726162">"Poskusno"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"Želite vklopiti Bluetooth?"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"Če želite povezati tipkovnico in tablični računalnik, vklopite Bluetooth."</string>
@@ -479,7 +480,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Uporabi"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Potrditev nastavitev"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Zaradi nekaterih barvnih nastavitev lahko postane ta naprava neuporabna. Kliknite »V redu«, če želite potrditi te barvne nastavitve. V nasprotnem primeru se bodo čez 10 sekund ponastavile na prvotno vrednost."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Akumulator (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Poraba akumulatorja"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Varčevanje z energijo akumulatorja med polnjenjem ni na voljo"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Varčevanje z energijo akumulatorja"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Omeji zmogljivost delovanja in prenos podatkov v ozadju"</string>
@@ -523,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Izbira gumba tipkovnice"</string>
     <string name="preview" msgid="9077832302472282938">"Predogled"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Povlecite, če želite dodati ploščice"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Uredi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index d679a58..3f25e7d 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"gozhdimi i ekranit"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"kërko"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nuk mundi të nisej."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> është i çaktivizuar në modalitetin e sigurt."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historiku"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Pastro"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Ndaje horizontalisht"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"Zbato"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Konfirmo cilësimet"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Disa cilësime ngjyrash mund ta bëjnë këtë pajisje të papërdorshme. Kliko OK për të konfirmuar këto cilësime ngjyrash, përndryshe këto cilësime do të rivendosen pas 10 sekondash."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Bateria (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"Përdorimi i baterisë"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"\"Kursyesi i baterisë\" nuk është i disponueshëm gjatë karikimit"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kursyesi i baterisë"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Pakëson veprimtarinë dhe të dhënat në sfond"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Zgjidh butonin e tastierës"</string>
     <string name="preview" msgid="9077832302472282938">"Pamja paraprake"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Zvarrit për të shtuar pllakëzat"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Redakto"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index fe3d121..8d54ca2 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -302,6 +302,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"качење екрана"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Историја"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Обриши"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Подели хоризонтално"</string>
@@ -478,7 +480,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Примени"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Потврдите подешавања"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Нека подешавања боја могу да учине уређај неупотребљивим. Кликните на Потврди да бисте потврдили ова подешавања боја, пошто ће се у супротном ова подешавања ресетовати након 10 секунди."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Батерија (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Уштеда батерије није доступна током пуњења"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Уштеда батерије"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Смањује перформансе и позадинске податке"</string>
@@ -522,4 +525,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Изаберите дугме за тастатуру"</string>
     <string name="preview" msgid="9077832302472282938">"Преглед"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Превуците да бисте додали плочице"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Измени"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e4d5d97..2a91962 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fästa skärmen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historik"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Rensa"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Dela horisontellt"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Verkställ"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Bekräfta inställningarna"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Vissa färginställningar kan göra den här enheten oanvändbar. Klicka på OK om du vill bekräfta färginställningarna, annars återställs inställningarna efter 10 sekunder."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Batteri (<xliff:g id="ID_1">%1$d</xliff:g> %%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Batterisparläget är inte tillgängligt vid laddning"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Batterisparläge"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Minskar prestanda och bakgrundsdata"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Välj tangentbordsknapp"</string>
     <string name="preview" msgid="9077832302472282938">"Förhandsgranskning"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Lägg till rutor genom att dra"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Redigera"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index e60496c..55f0213 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"kudumisha programu moja"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Historia"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Futa"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gawanya Mlalo"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Tumia"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Thibitisha mipangilio"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Baadhi ya mipangilio ya rangi inaweza kufanya kifaa hiki kisitumike. Bofya Sawa ili uthibitishe mipangilio hii ya rangi, vinginevyo, mipangilio hii itajiweka upya baada ya sekunde 10."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Betri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Kiokoa Betri hakipatikani unapochaji betri"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Kiokoa Betri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Hupunguza data ya chini chini na utendaji"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Chagua Kitufe cha Kibodi"</string>
     <string name="preview" msgid="9077832302472282938">"Onyesho la kuchungulia"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Buruta ili uongeze vigae"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Badilisha"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml
index 7e8d802..6594bd28 100644
--- a/packages/SystemUI/res/values-sw600dp-land/config.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/config.xml
@@ -19,5 +19,8 @@
          card. -->
     <integer name="keyguard_max_notification_count">3</integer>
 
+    <!-- Whether QuickSettings is in a phone landscape -->
+    <bool name="quick_settings_wide">false</bool>
+
     <integer name="quick_settings_num_columns">3</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index be5b856..4ed15d5 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -37,4 +37,7 @@
 
     <dimen name="navigation_key_width">162dp</dimen>
     <dimen name="navigation_key_padding">42dp</dimen>
+
+    <dimen name="battery_detail_graph_space_top">27dp</dimen>
+    <dimen name="battery_detail_graph_space_bottom">27dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index c0652d8..122413d 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -95,4 +95,10 @@
     <dimen name="navigation_key_padding">25dp</dimen>
 
     <dimen name="qs_expand_margin">0dp</dimen>
+
+    <!-- The top padding for the task stack. -->
+    <dimen name="recents_stack_top_padding">40dp</dimen>
+
+    <!-- The side padding for the task stack. -->
+    <dimen name="recents_stack_left_right_padding">64dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml
index 7cee381..8fe6be9 100644
--- a/packages/SystemUI/res/values-sw720dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp/dimens.xml
@@ -31,6 +31,8 @@
 
     <!-- The radius of the rounded corners on a task view. -->
     <dimen name="recents_task_view_rounded_corners_radius">3dp</dimen>
+    <!-- The radius of the rounded corners on a task view's shadow. -->
+    <dimen name="recents_task_view_shadow_rounded_corners_radius">12dp</dimen>
 
     <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
      max value is used when no notifications are displaying, and the min value is when the
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 1bb10e7..ecfc446 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"திரையை பின் செய்தல்"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"வரலாறு"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"அழி"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"கிடைமட்டமாகப் பிரி"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"பயன்படுத்து"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"அமைப்புகளை உறுதிப்படுத்து"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"சில வண்ண அமைப்புகள் இந்தச் சாதனத்தைப் பயன்படுத்த முடியாதபடி செய்யலாம். இந்த வண்ண அமைப்புகளை உறுதிப்படுத்த, சரி என்பதைக் கிளிக் செய்யவும், இல்லையெனில் இந்த அமைப்புகள் 10 வினாடிகளுக்குப் பின் மீட்டமைக்கப்படும்."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"பேட்டரி (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"சார்ஜ் செய்யும் போது பேட்டரி சேமிப்பானைப் பயன்படுத்த முடியாது"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"பேட்டரி சேமிப்பான்"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"செயல்திறனையும் பின்புலத்தில் தரவு செயலாக்கப்படுவதையும் குறைக்கும்"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"விசைப்பலகைப் பொத்தானைத் தேர்ந்தெடுக்கவும்"</string>
     <string name="preview" msgid="9077832302472282938">"மாதிரிக்காட்சி"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"கட்டங்களைச் சேர்க்க, இழுக்கவும்"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"மாற்று"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index e57113e..4f702b6 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -301,6 +301,7 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"స్క్రీన్ పిన్నింగ్"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
+    <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్‌లో నిలిపివేయబడింది."</string>
     <string name="recents_history_button_label" msgid="5153358867807604821">"చరిత్ర"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"తీసివేయి"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"సమతలంగా విభజించు"</string>
@@ -477,7 +478,7 @@
     <string name="color_apply" msgid="9212602012641034283">"వర్తింపజేయి"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"సెట్టింగ్‌లను నిర్ధారించండి"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"కొన్ని రంగు సెట్టింగ్‌ల వలన ఈ పరికరం ఉపయోగించలేని విధంగా అయిపోవచ్చు. ఈ రంగు సెట్టింగ్‌లను నిర్ధారించడానికి సరే క్లిక్ చేయండి లేదంటే ఈ సెట్టింగ్‌లు 10 సెకన్ల తర్వాత రీసెట్ చేయబడతాయి."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"బ్యాటరీ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <string name="battery_panel_title" msgid="7944156115535366613">"బ్యాటరీ వినియోగం"</string>
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ఛార్జ్ అవుతున్న సమయంలో బ్యాటరీ సేవర్ అందుబాటులో ఉండదు"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"బ్యాటరీ సేవర్"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"పనితీరుని మరియు నేపథ్య డేటాను తగ్గిస్తుంది"</string>
@@ -521,4 +522,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"కీబోర్డ్ బటన్‌ను ఎంచుకోండి"</string>
     <string name="preview" msgid="9077832302472282938">"పరిదృశ్యం"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"టైల్‌లను జోడించడానికి లాగండి"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"సవరించు"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 6a61f13..bc7e26f 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"การตรึงหน้าจอ"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"ประวัติ"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"ล้าง"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"แยกในแนวนอน"</string>
@@ -446,8 +448,8 @@
     <string name="clock_seconds_desc" msgid="6282693067130470675">"แสดงวินาทีของนาฬิกาในแถบสถานะ อาจส่งผลต่ออายุแบตเตอรี"</string>
     <string name="qs_rearrange" msgid="8060918697551068765">"จัดเรียงการตั้งค่าด่วนใหม่"</string>
     <string name="show_brightness" msgid="6613930842805942519">"แสดงความสว่างในการตั้งค่าด่วน"</string>
-    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"เปิดใช้ตัวเร่งการกวาดขึ้นเพื่อแยกหน้าจอ"</string>
-    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"เปิดใช้ท่าทางสัมผัสเพื่อเข้าสู่โหมดแยกหน้าจอโดยกวาดขึ้นจากปุ่มภาพรวม"</string>
+    <string name="overview_nav_bar_gesture" msgid="1852503363271291341">"เปิดใช้ตัวเร่งการเลื่อนขึ้นเพื่อแยกหน้าจอ"</string>
+    <string name="overview_nav_bar_gesture_desc" msgid="6329167382305102615">"เปิดใช้ท่าทางสัมผัสเพื่อเข้าสู่โหมดแยกหน้าจอโดยเลื่อนขึ้นจากปุ่มภาพรวม"</string>
     <string name="experimental" msgid="6198182315536726162">"ทดสอบ"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"เปิดบลูทูธไหม"</string>
     <string name="enable_bluetooth_message" msgid="9106595990708985385">"หากต้องการเชื่อมต่อแป้นพิมพ์กับแท็บเล็ต คุณต้องเปิดบลูทูธก่อน"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"ใช้"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ยืนยันการตั้งค่า"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"การตั้งค่าสีบางอย่างอาจทำให้อุปกรณ์นี้ใช้งานไม่ได้ คลิกตกลงเพื่อยืนยันการตั้งค่าสีเหล่านี้ มิฉะนั้นระบบจะรีเซ็ตการตั้งค่าหลังจาก 10 วินาที"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"แบตเตอรี่ (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"ไม่สามารถใช้โหมดประหยัดแบตเตอรี่ระหว่างการชาร์จ"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"โหมดประหยัดแบตเตอรี่"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"ลดประสิทธิภาพการทำงานและข้อมูลแบ็กกราวด์"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"เลือกปุ่มแป้นพิมพ์"</string>
     <string name="preview" msgid="9077832302472282938">"ดูตัวอย่าง"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ลากเพื่อเพิ่มชิ้นส่วน"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"แก้ไข"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 038867d..ab800d4 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pagpi-pin sa screen"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"History"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"I-clear"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Split Horizontal"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Ilapat"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Kumpirmahin ang mga setting"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Maaaring hindi magamit ang device na ito dahil sa ilang setting ng kulay. I-click ang OK upang kumpirmahin ang mga setting ng kulay na ito, kung hindi ay mare-reset ang mga setting na ito pagkatapos ng 10 segundo."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Baterya (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Hindi available ang Pangtipid sa Baterya kapag nagcha-charge"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pangtipid sa Baterya"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Binabawasan ang pagganap at data sa background"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Pumili ng Button na Keyboard"</string>
     <string name="preview" msgid="9077832302472282938">"I-preview"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Mag-drag upang magdagdag ng mga tile"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"I-edit"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 0da92bb..1acffad 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekran sabitleme"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Geçmiş"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sil"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Yatay Ayırma"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Uygula"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Ayarları onaylayın"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Bazı renkler bu cihazı kullanılmaz yapabilir. Bu renkleri onaylamak için Tamam\'ı tıklayın. Tıklamazsanız bu ayarlar 10 saniye sonra sıfırlanacaktır."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Pil (%%<xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Şarj sırasında Pil Tasarrufu özelliği kullanılamaz"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Pil Tasarrufu"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Performansı ve arka plan verilerini azaltır"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Klavye Düğmesini Seçin"</string>
     <string name="preview" msgid="9077832302472282938">"Önizle"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Blok eklemek için sürükleyin"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Düzenle"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index eaf4d39..0a00467 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -303,6 +303,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"закріпити екран"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Історія"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Очистити"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Розділити горизонтально"</string>
@@ -479,7 +481,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Застосувати"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Підтвердити налаштування"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Деякі налаштування кольорів можуть зробити цей пристрій непридатним для використання. Натисніть OK, щоб підтвердити налаштування, інакше їх буде скинуто через 10 секунд."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Акумулятор (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Режим економії заряду акумулятора недоступний під час заряджання"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Режим економії заряду акумулятора"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Знижується продуктивність і обмежується обмін даними у фоновому режимі"</string>
@@ -523,4 +526,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Вибрати кнопку клавіатури"</string>
     <string name="preview" msgid="9077832302472282938">"Переглянути"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Перетягуйте фрагменти, щоб додавати їх"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Редагувати"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 8bfd7c6..0e1d78f 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"اسکرین کو پن کرنا"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"سرگزشت"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"صاف کریں"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"بلحاظ افقی الگ کریں"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"لاگو کریں"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"ترتیبات کی توثیق کریں"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"رنگوں کی کچھ ترتیبات اس آلے کو ناقابل استعمال بنا سکتی ہیں۔ رنگوں کی ان ترتیبات کی توثیق کرنے کیلئے ٹھیک ہے پر کلک کریں، بصورت دیگر 10 سیکنڈ بعد یہ ترتیبات ری سیٹ ہو جائیں گی۔"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"بیٹری (%%<xliff:g id="ID_1">%1$d</xliff:g>)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"چارجنگ کے دوران بیٹری سیور دستیاب نہیں ہے"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"بیٹری سیور"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"کارکردگی اور پس منظر کا ڈیٹا کم کر دیتا ہے"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"کی بورڈ بٹن منتخب کریں"</string>
     <string name="preview" msgid="9077832302472282938">"پیش منظر"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"ٹائٹلز شامل کرنے کیلئے گھسیٹیں"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"ترمیم کریں"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 315a869..68393ff 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -67,12 +67,12 @@
     <string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Bu qurilmaga ayni paytda o‘z hisobi bilan kirgan foydalanuvchi USB orqali tuzatish funksiyasini faollashtira olmaydi. Undan foydalanish uchun administrator profiliga o‘ting."</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Ekranga moslashtirish"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Ekran hajmida cho‘zish"</string>
-    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Ekran surati saqlanmoqda…"</string>
-    <string name="screenshot_saving_title" msgid="8242282144535555697">"Ekran surati saqlanmoqda…"</string>
-    <string name="screenshot_saving_text" msgid="2419718443411738818">"Ekran surati saqlanadi."</string>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran surati olindi."</string>
-    <string name="screenshot_saved_text" msgid="1152839647677558815">"Ekraningiz suratini ko‘rish uchun bosing."</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"Ekran surati olinmadi."</string>
+    <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Skrinshot saqlanmoqda…"</string>
+    <string name="screenshot_saving_title" msgid="8242282144535555697">"Skrinshot saqlanmoqda…"</string>
+    <string name="screenshot_saving_text" msgid="2419718443411738818">"Skrinshot saqlanmoqda."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinshot saqlandi."</string>
+    <string name="screenshot_saved_text" msgid="1152839647677558815">"Ko‘rish uchun bu yerga bosing."</string>
+    <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinshot saqlanmadi."</string>
     <string name="screenshot_failed_text" msgid="1260203058661337274">"Ekrandan suratga olib bo‘lmadi: xotirada joy kam yoki ilova/tashkilot bunga ruxsat bermagan."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl ko‘chirish moslamalari"</string>
     <string name="use_mtp_button_title" msgid="4333504413563023626">"Media pleyer sifatida ulash (MTP)"</string>
@@ -296,11 +296,13 @@
     <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Cheklov: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ogohlantirish: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_work_mode_label" msgid="6244915274350490429">"Ish rejimi"</string>
-    <string name="recents_empty_message" msgid="8682129509540827999">"Siz yaqinda ishlatgan ilova ekranlari bu yerda ko‘rinadi"</string>
+    <string name="recents_empty_message" msgid="8682129509540827999">"Bu yerda yaqinda ishlatilgan ilovalar ko‘rsatiladi"</string>
     <string name="recents_app_info_button_label" msgid="2890317189376000030">"Ilova haqida ma’lumot"</string>
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"o‘zgarmas ekran"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Jurnal"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Tozalash"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Gorizontal yo‘nalishda bo‘lish"</string>
@@ -374,7 +376,7 @@
     <string name="empty_shade_text" msgid="708135716272867002">"Bildirishnomalar yo‘q"</string>
     <string name="device_owned_footer" msgid="3802752663326030053">"Qurilma kuzatilishi mumkin"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profil kuzatilishi mumkin"</string>
-    <string name="vpn_footer" msgid="2388611096129106812">"Tarmoq kuzatuv ostida bo‘lishi mumkin"</string>
+    <string name="vpn_footer" msgid="2388611096129106812">"Tarmoqni kuzatish mumkin"</string>
     <string name="monitoring_title_device_owned" msgid="7121079311903859610">"Qurilmalarni kuzatish"</string>
     <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Profilni kuzatish"</string>
     <string name="monitoring_title" msgid="169206259253048106">"Tarmoqlarni kuzatish"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Qo‘llash"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Sozlamalarni tasdiqlang"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ba’zi rang sozlamalari qurilmadan foydalanishni qiyinlashtirish mumkin. Tanlgan parametrlarni tasdiqlash uchun “OK” tugmasini bosing. Aks holda, ular 10 soniyadan so‘ng qayta tiklanadi."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Quvvat (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Quvvat tejash rejimidan quvvatlash vaqtida foydalanib bo‘lmaydi"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Quvvat tejash rejimi"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Unumdorlikni pasaytiradi va fonda internetdan foydalanishni cheklaydi"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Klaviatura tugmasini tanlang"</string>
     <string name="preview" msgid="9077832302472282938">"Oldindan ko‘rish"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Fragmentlar qo‘shish uchun torting"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Tahrirlash"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index b0209ee..d4c7317 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"khóa màn hình"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Lịch sử"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Xóa"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Phân tách ngang"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Áp dụng"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Xác nhận cài đặt"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Một số cài đặt màu có thể khiến thiết bị này không sử dụng được. Hãy nhấp vào OK để xác nhận các cài đặt màu này, nếu không những cài đặt này sẽ được đặt lại sau 10 giây."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Pin (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Trình tiết kiệm pin không khả dụng trong khi sạc"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Trình tiết kiệm pin"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Giảm hiệu suất và dữ liệu nền"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Chọn nút trên bàn phím"</string>
     <string name="preview" msgid="9077832302472282938">"Xem trước"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Kéo để thêm ô"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Chỉnh sửa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-w550dp-land/config.xml b/packages/SystemUI/res/values-w550dp-land/config.xml
index 71e54a1..16d5317 100644
--- a/packages/SystemUI/res/values-w550dp-land/config.xml
+++ b/packages/SystemUI/res/values-w550dp-land/config.xml
@@ -20,5 +20,9 @@
 <!-- These resources are around just to allow their values to be customized
      for different hardware and product builds. -->
 <resources>
+
+    <!-- Whether QuickSettings is in a phone landscape -->
+    <bool name="quick_settings_wide">true</bool>
+
     <integer name="quick_settings_num_columns">4</integer>
 </resources>
diff --git a/packages/SystemUI/res/values-w550dp-land/dimens.xml b/packages/SystemUI/res/values-w550dp-land/dimens.xml
index 4160c83..cd17bed 100644
--- a/packages/SystemUI/res/values-w550dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-w550dp-land/dimens.xml
@@ -20,4 +20,7 @@
     <dimen name="notification_panel_width">544dp</dimen>
 
     <dimen name="qs_expand_margin">32dp</dimen>
+
+    <dimen name="battery_detail_graph_space_top">9dp</dimen>
+    <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a852221..8a3723a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"固定屏幕"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"历史记录"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"应用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"确认设置"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分颜色设置可能会导致此设备无法使用。请点击“确定”确认这些颜色设置,否则,系统将在 10 秒后重置这些设置。"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"电池 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用节电助手"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"节电助手"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低性能并限制后台流量"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"选择键盘按钮"</string>
     <string name="preview" msgid="9077832302472282938">"预览"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"拖动即可添加图块"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"修改"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 3402fc2..675d0f3 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"記錄"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"套用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"確認設定"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分顏色設定會令此裝置無法使用。請按一下 [確定] 加以確認,否則這些顏色設定將於 10 秒後重設。"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"電池電量 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用「省電模式」"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"省電模式"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景數據傳輸"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"選取鍵盤按鈕"</string>
     <string name="preview" msgid="9077832302472282938">"預覽"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"拖曳即可新增圖塊"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"編輯"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index b9e3486..08cbb17 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"紀錄"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"清除"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"水平分割"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"套用"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"確認設定"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"部分顏色設定可能會造成這部裝置無法使用。請按一下 [確定] 來確認您要使用這類顏色設定,否則系統將在 10 秒後重設這些設定。"</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"電池 (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充電時無法使用節約耗電量模式"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"節約耗電量"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低效能並限制背景資料傳輸"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"選取鍵盤按鍵"</string>
     <string name="preview" msgid="9077832302472282938">"預覽"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"拖曳即可新增圖塊"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"編輯"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 9f4878a..df58a62 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -301,6 +301,8 @@
     <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ukuphina isikrini"</string>
     <string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string>
     <string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string>
+    <!-- no translation found for recents_launch_disabled_message (1624523193008871793) -->
+    <skip />
     <string name="recents_history_button_label" msgid="5153358867807604821">"Umlando"</string>
     <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Sula"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Hlukanisa okuvundlile"</string>
@@ -477,7 +479,8 @@
     <string name="color_apply" msgid="9212602012641034283">"Sebenzisa"</string>
     <string name="color_revert_title" msgid="4746666545480534663">"Qinisekisa izilungiselelo"</string>
     <string name="color_revert_message" msgid="9116001069397996691">"Ezinye izilungiselelo zombala zingenza le divayisi ingasebenziseki. Chofoza ku-KULUNGILE ukuze uqinisekise lezi zilungiselelo zombala, uma kungenjalo lezi zilungiselelo zizosethwa kabusha ngemuva kwamasekhondi angu-10."</string>
-    <string name="battery_panel_title" msgid="3476715163685592453">"Ibhethri (<xliff:g id="ID_1">%1$d</xliff:g>%%)"</string>
+    <!-- no translation found for battery_panel_title (7944156115535366613) -->
+    <skip />
     <string name="battery_detail_charging_summary" msgid="1279095653533044008">"Isilondolozi sebhethri asitholakali ngesikhathi sokushaja"</string>
     <string name="battery_detail_switch_title" msgid="6285872470260795421">"Isilondolozi sebhethri"</string>
     <string name="battery_detail_switch_summary" msgid="9049111149407626804">"Sehlisa ukusebenza nedatha yasemuva"</string>
@@ -521,4 +524,5 @@
     <string name="select_keycode" msgid="7413765103381924584">"Khetha inkinobho yekhibhodi"</string>
     <string name="preview" msgid="9077832302472282938">"Hlola kuqala"</string>
     <string name="drag_to_add_tiles" msgid="7058945779098711293">"Hudula ukuze ungeze amathayili"</string>
+    <string name="qs_edit" msgid="2232596095725105230">"Hlela"</string>
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index a9b8df2..4cd920a 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -52,8 +52,12 @@
     <!-- Tint color for the content on the notification overflow card. -->
     <color name="keyguard_overflow_content_color">#ff686868</color>
 
+    <!-- The disabled recents task bar background color. -->
+    <color name="recents_task_bar_disabled_background_color">#ff676767</color>
     <!-- The default recents task bar background color. -->
     <color name="recents_task_bar_default_background_color">#ffe6e6e6</color>
+    <!-- The default recents task view background color. -->
+    <color name="recents_task_view_default_background_color">#fff3f3f3</color>
     <!-- The recents task bar light text color to be drawn on top of dark backgrounds. -->
     <color name="recents_task_bar_light_text_color">#ffeeeeee</color>
     <!-- The recents task bar dark text color to be drawn on top of light backgrounds. -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index a6ba8b5..4e1680d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -89,6 +89,9 @@
     <!-- Min alpha % that recent items will fade to while being dismissed -->
     <integer name="config_recent_item_min_alpha">3</integer>
 
+    <!-- Whether QuickSettings is in a phone landscape -->
+    <bool name="quick_settings_wide">false</bool>
+
     <!-- The number of columns in the QuickSettings -->
     <integer name="quick_settings_num_columns">3</integer>
 
@@ -165,9 +168,6 @@
     <!-- The animation duration for entering and exiting the history. -->
     <integer name="recents_history_transition_duration">250</integer>
 
-    <!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
-    <integer name="recents_max_task_stack_view_dim">96</integer>
-
     <!-- The delay to enforce between each alt-tab key press. -->
     <integer name="recents_alt_tab_key_delay">200</integer>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e5e5710..aed5ab2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -162,7 +162,10 @@
     <dimen name="qs_tile_margin">16dp</dimen>
     <dimen name="qs_quick_tile_size">48dp</dimen>
     <dimen name="qs_quick_tile_padding">12dp</dimen>
-    <dimen name="qs_date_anim_translation">44.5dp</dimen>
+    <dimen name="qs_date_anim_translation">36dp</dimen>
+    <dimen name="qs_date_alarm_anim_translation">26dp</dimen>
+    <dimen name="qs_date_collapsed_text_size">14sp</dimen>
+    <dimen name="qs_date_text_size">16sp</dimen>
     <dimen name="qs_page_indicator_size">12dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
@@ -227,12 +230,14 @@
 
     <!-- The radius of the rounded corners on a task view. -->
     <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
+    <!-- The radius of the rounded corners on a task view's shadow. -->
+    <dimen name="recents_task_view_shadow_rounded_corners_radius">12dp</dimen>
 
     <!-- The min translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_min">16dp</dimen>
+    <dimen name="recents_task_view_z_min">3dp</dimen>
 
     <!-- The max translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_max">48dp</dimen>
+    <dimen name="recents_task_view_z_max">24dp</dimen>
 
     <!-- The amount to translate when animating the removal of a task. -->
     <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
@@ -249,15 +254,15 @@
     <!-- The height of the search bar space. -->
     <dimen name="recents_search_bar_space_height">64dp</dimen>
 
-    <!-- The side padding for the task stack as a percentage of the width. -->
-    <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.03333</item>
-
     <!-- The overscroll percentage allowed on the stack. -->
     <item name="recents_stack_overscroll_percentage" format="float" type="dimen">0.0875</item>
 
-    <!-- The top offset for the task stack. -->
+    <!-- The top padding for the task stack. -->
     <dimen name="recents_stack_top_padding">16dp</dimen>
 
+    <!-- The side padding for the task stack. -->
+    <dimen name="recents_stack_left_right_padding">16dp</dimen>
+
     <!-- The dimesnsions of the dismiss all recents button. -->
     <dimen name="recents_dismiss_all_button_size">48dp</dimen>
 
@@ -273,8 +278,11 @@
     <!-- The amount to allow the stack to overscroll. -->
     <dimen name="recents_stack_overscroll">24dp</dimen>
 
-    <!-- The size of the peek area at the top of the stack. -->
-    <dimen name="recents_layout_focused_peek_size">@dimen/recents_history_button_height</dimen>
+    <!-- The size of the peek area at the top of the stack (below the status bar). -->
+    <dimen name="recents_layout_focused_top_peek_size">@dimen/recents_history_button_height</dimen>
+
+    <!-- The size of each task peek area at the bottom of the stack (above the nav bar). -->
+    <dimen name="recents_layout_focused_bottom_task_peek_size">16dp</dimen>
 
     <!-- The height of the history button. -->
     <dimen name="recents_history_button_height">48dp</dimen>
@@ -282,9 +290,6 @@
     <!-- The padding between freeform workspace tasks -->
     <dimen name="recents_freeform_workspace_task_padding">8dp</dimen>
 
-    <!-- Space reserved for the cards behind the top card in the top stack -->
-    <dimen name="top_stack_peek_amount">12dp</dimen>
-
     <!-- Space reserved for the cards behind the top card in the bottom stack -->
     <dimen name="bottom_stack_peek_amount">12dp</dimen>
 
@@ -295,9 +300,6 @@
     <!-- The height of the area before the bottom stack in which the notifications slow down -->
     <dimen name="bottom_stack_slow_down_length">12dp</dimen>
 
-    <!-- The height of the area before the top stack in which the notifications slow down -->
-    <dimen name="top_stack_slow_down_length">12dp</dimen>
-
     <!-- Z distance between notifications if they are in the stack -->
     <dimen name="z_distance_between_notifications">0.5dp</dimen>
 
@@ -599,9 +601,6 @@
     <dimen name="fab_elevation">12dp</dimen>
     <dimen name="fab_press_translation_z">9dp</dimen>
 
-    <!-- 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">4dp</dimen>
 
@@ -610,4 +609,7 @@
 
     <dimen name="battery_height">14.5dp</dimen>
     <dimen name="battery_width">9.5dp</dimen>
+
+    <dimen name="battery_detail_graph_space_top">27dp</dimen>
+    <dimen name="battery_detail_graph_space_bottom">27dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6ff9be1..fa5b1a9 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -714,6 +714,8 @@
     <string name="recents_search_bar_label">search</string>
     <!-- Recents: Launch error string. [CHAR LIMIT=NONE] -->
     <string name="recents_launch_error_message">Could not start <xliff:g id="app" example="Calendar">%s</xliff:g>.</string>
+    <!-- Recents: Launch disabled string. [CHAR LIMIT=NONE] -->
+    <string name="recents_launch_disabled_message"><xliff:g id="app" example="Calendar">%s</xliff:g> is disabled in safe-mode.</string>
     <!-- Recents: Show history string. [CHAR LIMIT=NONE] -->
     <string name="recents_history_button_label">History</string>
     <!-- Recents: History clear all string. [CHAR LIMIT=NONE] -->
@@ -1174,18 +1176,13 @@
     <!-- Option to use new paging layout in quick settings [CHAR LIMIT=60] -->
     <string name="qs_paging" translatable="false">Use the new Quick Settings</string>
 
-    <!-- Toggles fast-toggling recents via the recents button. DO NOT TRANSLATE -->
-    <string name="overview_fast_toggle_via_button">Enable fast toggle</string>
+    <!-- Disables fast-toggling recents via the recents button. DO NOT TRANSLATE -->
+    <string name="overview_disable_fast_toggle_via_button">Disable fast toggle</string>
     <!-- Description for the toggle for fast-toggling recents via the recents button. DO NOT TRANSLATE -->
-    <string name="overview_fast_toggle_via_button_desc">Enable launch timeout while paging</string>
-
-    <!-- Toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
-    <string name="overview_initial_state_paging">Initialize to paging</string>
-    <!-- Description for the toggle to set the initial scroll state to be paging or stack. DO NOT TRANSLATE -->
-    <string name="overview_initial_state_paging_desc">Determines whether Overview will initially be in a stacked or paged state</string>
+    <string name="overview_disable_fast_toggle_via_button_desc">Disable launch timeout while paging</string>
 
     <!-- Toggle to enable the gesture to enter split-screen by swiping up from the Overview button. [CHAR LIMIT=60]-->
-    <string name="overview_nav_bar_gesture">Enable split-screen swipe-up accelerator</string>
+    <string name="overview_nav_bar_gesture">Enable split-screen swipe-up gesture</string>
     <!-- Description for the toggle to enable the gesture to enter split-screen by swiping up from the Overview button. [CHAR LIMIT=NONE]-->
     <string name="overview_nav_bar_gesture_desc">Enable gesture to enter split-screen by swiping up from the Overview button</string>
 
@@ -1193,7 +1190,6 @@
          settings are -->
     <string name="experimental">Experimental</string>
 
-    <string name="save" translatable="false">Save</string>
     <string name="qs_customize" translatable="false">Allow long-press customize in Quick Settings</string>
     <string name="qs_customize_info" translatable="false">Info</string>
     <string name="qs_customize_remove" translatable="false">Remove</string>
@@ -1284,7 +1280,7 @@
     <string name="color_modification_b" translatable="false">B</string>
 
     <!-- Title of the battery settings detail panel [CHAR LIMIT=20] -->
-    <string name="battery_panel_title">Battery (<xliff:g name="pattery_percent" example="52">%1$d</xliff:g>%%)</string>
+    <string name="battery_panel_title">Battery usage</string>
 
     <!-- Summary of battery saver not available [CHAR LIMIT=NONE] -->
     <string name="battery_detail_charging_summary">Battery Saver not available during charging</string>
@@ -1405,4 +1401,7 @@
     <!-- Label for area where tiles can be dragged out of [CHAR LIMIT=60] -->
     <string name="drag_to_add_tiles">Drag to add tiles</string>
 
+    <!-- Button to edit the tile ordering of quick settings [CHAR LIMIT=60] -->
+    <string name="qs_edit">Edit</string>
+
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 60a9fc2..a51b931 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -300,7 +300,7 @@
     </style>
 
     <style name="TunerPreferenceTheme" parent="@android:style/Theme.Material.Settings">
-        <item name="@dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
+        <item name="dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
     </style>
 
     <style name="TextAppearance.NotificationGuts">
diff --git a/packages/SystemUI/res/values/values_tv.xml b/packages/SystemUI/res/values/values_tv.xml
index 45cdc07..1fcc9e4 100644
--- a/packages/SystemUI/res/values/values_tv.xml
+++ b/packages/SystemUI/res/values/values_tv.xml
@@ -14,5 +14,5 @@
 limitations under the License.
 -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-    <item format="float" type="raw" name="unselected_scale">1.0</item>
-</resources>
\ No newline at end of file
+    <item format="float" type="integer" name="unselected_scale">1.0</item>
+</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 4de4ced..39281bc 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -113,14 +113,9 @@
         android:title="@string/overview" >
 
         <com.android.systemui.tuner.TunerSwitch
-            android:key="overview_initial_state_paging"
-            android:title="@string/overview_initial_state_paging"
-            android:summary="@string/overview_initial_state_paging_desc" />
-
-        <com.android.systemui.tuner.TunerSwitch
-            android:key="overview_fast_toggle_via_button"
-            android:title="@string/overview_fast_toggle_via_button"
-            android:summary="@string/overview_fast_toggle_via_button_desc" />
+            android:key="overview_disable_fast_toggle_via_button"
+            android:title="@string/overview_disable_fast_toggle_via_button"
+            android:summary="@string/overview_disable_fast_toggle_via_button_desc" />
 
         <com.android.systemui.tuner.TunerSwitch
             android:key="overview_nav_bar_gesture"
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
index 454d1ce..4845425 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java
@@ -62,6 +62,7 @@
             mPlusPaint;
     private float mTextHeight, mWarningTextHeight;
     private int mIconTint = Color.WHITE;
+    private float mOldDarkIntensity = 0f;
 
     private int mHeight;
     private int mWidth;
@@ -295,6 +296,9 @@
     }
 
     public void setDarkIntensity(float darkIntensity) {
+        if (darkIntensity == mOldDarkIntensity) {
+            return;
+        }
         int backgroundColor = getBackgroundColor(darkIntensity);
         int fillColor = getFillColor(darkIntensity);
         mIconTint = fillColor;
@@ -302,6 +306,7 @@
         mBoltPaint.setColor(fillColor);
         mChargeColor = fillColor;
         invalidateSelf();
+        mOldDarkIntensity = darkIntensity;
     }
 
     private int getBackgroundColor(float darkIntensity) {
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
index 43a1be1..9238928 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
@@ -40,4 +40,15 @@
     public static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
     /** The user tapped on the status bar to open quick settings, from shade. */
     public static final int SYSUI_TAP_TO_OPEN_QS = 10;
+
+    /** Secondary user tries binding to the system sysui service */
+    public static final int SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE = 1;
+    /** Secondary user is bound to the system sysui service */
+    public static final int SYSUI_RECENTS_CONNECTION_USER_SYSTEM_BOUND = 2;
+    /** Secondary user loses connection after system sysui has died */
+    public static final int SYSUI_RECENTS_CONNECTION_USER_SYSTEM_UNBOUND = 3;
+    /** System sysui registers secondary user's callbacks */
+    public static final int SYSUI_RECENTS_CONNECTION_SYSTEM_REGISTER_USER = 4;
+    /** System sysui unregisters secondary user's callbacks (after death) */
+    public static final int SYSUI_RECENTS_CONNECTION_SYSTEM_UNREGISTER_USER = 5;
 }
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
index a584cf6..1601675 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
+++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags
@@ -51,3 +51,13 @@
 # SearchPanelView.java
 # ---------------------------
 36050 sysui_searchpanel_touch (type|1),(x|1),(y|1)
+
+# ---------------------------
+# Recents.java, RecentsSystemUser.java
+# ---------------------------
+## type: 1: USER_BIND_SERVICE        Secondary user tries binding to the system sysui service
+##       2: USER_SYSTEM_BOUND        Secondary user is bound to the system sysui service
+##       3: USER_SYSTEM_UNBOUND      Secondary user loses connection after system sysui has died
+##       4: SYSTEM_REGISTER_USER     System sysui registers user's callbacks
+##       5: SYSTEM_UNREGISTER_USER   System sysui unregisters user's callbacks (after death)
+36060 sysui_recents_connection (type|1),(user|1)
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 958572f..90d56f7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -475,6 +475,23 @@
                     break;
             }
         }
+
+        @Override
+        public void onFingerprintAuthFailed() {
+            final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+            if (mLockPatternUtils.isSecure(currentUser)) {
+                mLockPatternUtils.getDevicePolicyManager().reportFailedFingerprintAttempt(
+                        currentUser);
+            }
+        }
+
+        @Override
+        public void onFingerprintAuthenticated(int userId) {
+            if (mLockPatternUtils.isSecure(userId)) {
+                mLockPatternUtils.getDevicePolicyManager().reportSuccessfulFingerprintAttempt(
+                        userId);
+            }
+        }
     };
 
     ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -1370,8 +1387,9 @@
      * @see #KEYGUARD_DONE
      */
     private void handleKeyguardDone(boolean authenticated) {
-        if (mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
-            mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed();
+        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+        if (mLockPatternUtils.isSecure(currentUser)) {
+            mLockPatternUtils.getDevicePolicyManager().reportKeyguardDismissed(currentUser);
         }
         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
         synchronized (this) {
@@ -1484,8 +1502,9 @@
      * @see #SHOW
      */
     private void handleShow(Bundle options) {
-        if (mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
-            mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured();
+        final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+        if (mLockPatternUtils.isSecure(currentUser)) {
+            mLockPatternUtils.getDevicePolicyManager().reportKeyguardSecured(currentUser);
         }
         synchronized (KeyguardViewMediator.this) {
             if (!mSystemReady) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index d723367..8e9857d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -6,7 +6,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-
 import com.android.internal.widget.PagerAdapter;
 import com.android.internal.widget.ViewPager;
 import com.android.systemui.R;
@@ -27,6 +26,7 @@
     private PageIndicator mPageIndicator;
 
     private int mNumPages;
+    private View mDecorGroup;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -55,7 +55,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mPageIndicator = (PageIndicator) findViewById(R.id.page_indicator);
-        ((LayoutParams) mPageIndicator.getLayoutParams()).isDecor = true;
+        mDecorGroup = findViewById(R.id.page_decor);
+        ((LayoutParams) mDecorGroup.getLayoutParams()).isDecor = true;
 
         mPages.add((TilePage) LayoutInflater.from(mContext)
                 .inflate(R.layout.qs_paged_page, this, false));
@@ -137,7 +138,7 @@
                 maxHeight = height;
             }
         }
-        setMeasuredDimension(getMeasuredWidth(), maxHeight + mPageIndicator.getMeasuredHeight());
+        setMeasuredDimension(getMeasuredWidth(), maxHeight + mDecorGroup.getMeasuredHeight());
     }
 
     private final Runnable mDistribute = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index cfe8d07..34dfd6c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -16,19 +16,39 @@
 
 package com.android.systemui.qs;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewTreeObserver;
 import android.widget.FrameLayout;
-
+import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.BaseStatusBarHeader;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
 
 /**
- * Wrapper view with background which contains {@link QSPanel}
+ * Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader}
+ *
+ * Also manages animations for the QS Header and Panel.
  */
 public class QSContainer extends FrameLayout {
+    private static final String TAG = "QSContainer";
+    private static final boolean DEBUG = false;
 
     private int mHeightOverride = -1;
     private QSPanel mQSPanel;
+    private QSDetail mQSDetail;
+    protected BaseStatusBarHeader mHeader;
+    private float mQsExpansion;
+    private boolean mQsExpanded;
+    private boolean mHeaderAnimating;
+    private boolean mKeyguardShowing;
+    private boolean mStackScrollerOverscrolling;
+
+    private long mDelay;
 
     public QSContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -38,6 +58,9 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mQSPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
+        mQSDetail = (QSDetail) findViewById(R.id.qs_detail);
+        mQSDetail.setQsPanel(mQSPanel);
+        mHeader = (BaseStatusBarHeader) findViewById(R.id.header);
     }
 
     @Override
@@ -62,15 +85,139 @@
      * during closing the detail panel, this already returns the smaller height.
      */
     public int getDesiredHeight() {
-        if (mQSPanel.isClosingDetail()) {
-            return mQSPanel.getGridHeight() + getPaddingTop() + getPaddingBottom();
+        if (mQSDetail.isClosingDetail()) {
+            return mQSPanel.getGridHeight() + mHeader.getCollapsedHeight() + getPaddingBottom();
         } else {
             return getMeasuredHeight();
         }
     }
 
     private void updateBottom() {
-        int height = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
+        int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight();
+        int height = (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
+                + mHeader.getCollapsedHeight();
         setBottom(getTop() + height);
+        mQSDetail.setBottom(getTop() + height);
     }
+
+    private void updateQsState() {
+        boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
+        mQSPanel.setExpanded(mQsExpanded);
+        mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+                ? View.VISIBLE
+                : View.INVISIBLE);
+        mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+                || (mQsExpanded && !mStackScrollerOverscrolling));
+        mQSPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    public BaseStatusBarHeader getHeader() {
+        return mHeader;
+    }
+
+    public QSPanel getQsPanel() {
+        return mQSPanel;
+    }
+
+    public boolean isShowingDetail() {
+        return mQSPanel.isShowingCustomize() || mQSDetail.isShowingDetail();
+    }
+
+    public void setHeaderClickable(boolean clickable) {
+        if (DEBUG) Log.d(TAG, "setHeaderClickable " + clickable);
+        mHeader.setClickable(clickable);
+    }
+
+    public void setExpanded(boolean expanded) {
+        if (DEBUG) Log.d(TAG, "setExpanded " + expanded);
+        mQsExpanded = expanded;
+        updateQsState();
+    }
+
+    public void setKeyguardShowing(boolean keyguardShowing) {
+        if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
+        mKeyguardShowing = keyguardShowing;
+        updateQsState();
+    }
+
+    public void setOverscrolling(boolean stackScrollerOverscrolling) {
+        if (DEBUG) Log.d(TAG, "setOverscrolling " + stackScrollerOverscrolling);
+        mStackScrollerOverscrolling = stackScrollerOverscrolling;
+        updateQsState();
+    }
+
+    public void setListening(boolean listening) {
+        if (DEBUG) Log.d(TAG, "setListening " + listening);
+        mQSPanel.setListening(listening);
+        mHeader.setListening(listening);
+    }
+
+    public void setQsExpansion(float expansion, float headerTranslation) {
+        if (DEBUG) Log.d(TAG, "setQSExpansion " + expansion + " " + headerTranslation);
+        mQsExpansion = expansion;
+        final float translationScaleY = expansion - 1;
+        if (!mHeaderAnimating) {
+            setTranslationY(mKeyguardShowing ? (translationScaleY * mHeader.getHeight())
+                    : headerTranslation);
+        }
+        mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
+        mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight());
+        mQSDetail.setFullyExpanded(expansion == 1);
+        updateBottom();
+    }
+
+    public void animateHeaderSlidingIn(long delay) {
+        if (DEBUG) Log.d(TAG, "animateHeaderSlidingIn");
+        // If the QS is already expanded we don't need to slide in the header as it's already
+        // visible.
+        if (!mQsExpanded) {
+            mHeaderAnimating = true;
+            mDelay = delay;
+            getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
+        }
+    }
+
+    public void animateHeaderSlidingOut() {
+        if (DEBUG) Log.d(TAG, "animateHeaderSlidingOut");
+        mHeaderAnimating = true;
+        animate().y(-mHeader.getHeight())
+                .setStartDelay(0)
+                .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
+                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        animate().setListener(null);
+                        mHeaderAnimating = false;
+                        updateQsState();
+                    }
+                })
+                .start();
+    }
+
+    private final ViewTreeObserver.OnPreDrawListener mStartHeaderSlidingIn
+            = new ViewTreeObserver.OnPreDrawListener() {
+        @Override
+        public boolean onPreDraw() {
+            getViewTreeObserver().removeOnPreDrawListener(this);
+            animate()
+                    .translationY(0f)
+                    .setStartDelay(mDelay)
+                    .setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
+                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
+                    .setListener(mAnimateHeaderSlidingInListener)
+                    .start();
+            setY(-mHeader.getHeight());
+            return true;
+        }
+    };
+
+    private final Animator.AnimatorListener mAnimateHeaderSlidingInListener
+            = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mHeaderAnimating = false;
+            updateQsState();
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
new file mode 100644
index 0000000..50c0cca
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.drawable.Animatable;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.TextView;
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.FontSizeUtils;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile.DetailAdapter;
+import com.android.systemui.statusbar.phone.QSTileHost;
+
+public class QSDetail extends LinearLayout {
+
+    private static final String TAG = "QSDetail";
+    private static final long FADE_DURATION = 300;
+
+    private final SparseArray<View> mDetailViews = new SparseArray<>();
+
+    private ViewGroup mDetailContent;
+    private TextView mDetailSettingsButton;
+    private TextView mDetailDoneButton;
+    private QSDetailClipper mClipper;
+    private DetailAdapter mDetailAdapter;
+    private QSPanel mQsPanel;
+
+    private View mQsDetailHeader;
+    private TextView mQsDetailHeaderTitle;
+    private Switch mQsDetailHeaderSwitch;
+    private ImageView mQsDetailHeaderProgress;
+
+    private QSTileHost mHost;
+
+    private boolean mScanState;
+    private boolean mClosingDetail;
+    private boolean mFullyExpanded;
+    private View mQsDetailHeaderBack;
+
+    public QSDetail(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        FontSizeUtils.updateFontSize(mDetailDoneButton, R.dimen.qs_detail_button_text_size);
+        FontSizeUtils.updateFontSize(mDetailSettingsButton, R.dimen.qs_detail_button_text_size);
+
+        for (int i = 0; i < mDetailViews.size(); i++) {
+            mDetailViews.valueAt(i).dispatchConfigurationChanged(newConfig);
+        }
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mDetailContent = (ViewGroup) findViewById(android.R.id.content);
+        mDetailSettingsButton = (TextView) findViewById(android.R.id.button2);
+        mDetailDoneButton = (TextView) findViewById(android.R.id.button1);
+
+        mQsDetailHeader = findViewById(R.id.qs_detail_header);
+        mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
+        mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
+        mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
+        mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
+
+        updateDetailText();
+
+        mClipper = new QSDetailClipper(this);
+
+        final OnClickListener doneListener = new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                announceForAccessibility(
+                        mContext.getString(R.string.accessibility_desc_quick_settings));
+                mQsPanel.closeDetail();
+            }
+        };
+        mQsDetailHeaderBack.setOnClickListener(doneListener);
+        mDetailDoneButton.setOnClickListener(doneListener);
+    }
+
+    public void setQsPanel(QSPanel panel) {
+        mQsPanel = panel;
+        mQsPanel.setCallback(mQsPanelCallback);
+    }
+
+    public void setHost(QSTileHost host) {
+        mHost = host;
+    }
+    public boolean isShowingDetail() {
+        return mDetailAdapter != null;
+    }
+
+    public void setFullyExpanded(boolean fullyExpanded) {
+        mFullyExpanded = fullyExpanded;
+    }
+
+    private void updateDetailText() {
+        mDetailDoneButton.setText(R.string.quick_settings_done);
+        mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
+    }
+
+    public void updateResources() {
+        updateDetailText();
+    }
+
+    public boolean isClosingDetail() {
+        return mClosingDetail;
+    }
+
+    private void handleShowingDetail(final QSTile.DetailAdapter adapter, int x, int y) {
+        final boolean showingDetail = adapter != null;
+        setClickable(showingDetail);
+        if (showingDetail) {
+            mQsDetailHeaderTitle.setText(adapter.getTitle());
+            final Boolean toggleState = adapter.getToggleState();
+            if (toggleState == null) {
+                mQsDetailHeaderSwitch.setVisibility(INVISIBLE);
+                mQsDetailHeader.setClickable(false);
+            } else {
+                mQsDetailHeaderSwitch.setVisibility(VISIBLE);
+                mQsDetailHeaderSwitch.setChecked(toggleState);
+                mQsDetailHeader.setClickable(true);
+                mQsDetailHeader.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        boolean checked = !mQsDetailHeaderSwitch.isChecked();
+                        mQsDetailHeaderSwitch.setChecked(checked);
+                        adapter.setToggleState(checked);
+                    }
+                });
+            }
+        }
+
+        boolean visibleDiff = (mDetailAdapter != null) != (adapter != null);
+        if (!visibleDiff && mDetailAdapter == adapter) return;  // already in right state
+        AnimatorListener listener = null;
+        if (adapter != null) {
+            int viewCacheIndex = adapter.getMetricsCategory();
+            View detailView = adapter.createDetailView(mContext, mDetailViews.get(viewCacheIndex),
+                    mDetailContent);
+            if (detailView == null) throw new IllegalStateException("Must return detail view");
+
+            final Intent settingsIntent = adapter.getSettingsIntent();
+            mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
+            mDetailSettingsButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    mHost.startActivityDismissingKeyguard(settingsIntent);
+                }
+            });
+
+            mDetailContent.removeAllViews();
+            mDetailContent.addView(detailView);
+            mDetailViews.put(viewCacheIndex, detailView);
+            MetricsLogger.visible(mContext, adapter.getMetricsCategory());
+            announceForAccessibility(mContext.getString(
+                    R.string.accessibility_quick_settings_detail,
+                    adapter.getTitle()));
+            mDetailAdapter = adapter;
+            listener = mHideGridContentWhenDone;
+            setVisibility(View.VISIBLE);
+        } else {
+            if (mDetailAdapter != null) {
+                MetricsLogger.hidden(mContext, mDetailAdapter.getMetricsCategory());
+            }
+            mClosingDetail = true;
+            mDetailAdapter = null;
+            listener = mTeardownDetailWhenDone;
+            mQsPanel.setGridContentVisibility(true);
+            mQsPanelCallback.onScanStateChanged(false);
+        }
+        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+        if (visibleDiff) {
+            if (mFullyExpanded || mDetailAdapter != null) {
+                setAlpha(1);
+                mClipper.animateCircularClip(x, y, mDetailAdapter != null, listener);
+            } else {
+                animate().alpha(0)
+                        .setDuration(FADE_DURATION)
+                        .setListener(listener)
+                        .start();
+            }
+        }
+    }
+
+    private void handleToggleStateChanged(boolean state) {
+        mQsDetailHeaderSwitch.setChecked(state);
+    }
+
+    private void handleScanStateChanged(boolean state) {
+        if (mScanState == state) return;
+        mScanState = state;
+        final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
+        if (state) {
+            mQsDetailHeaderProgress.animate().alpha(1f);
+            anim.start();
+        } else {
+            mQsDetailHeaderProgress.animate().alpha(0f);
+            anim.stop();
+        }
+    }
+
+    private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
+        @Override
+        public void onToggleStateChanged(final boolean state) {
+            post(new Runnable() {
+                @Override
+                public void run() {
+                    handleToggleStateChanged(state);
+                }
+            });
+        }
+
+        @Override
+        public void onShowingDetail(final DetailAdapter detail, final int x, final int y) {
+            post(new Runnable() {
+                @Override
+                public void run() {
+                    handleShowingDetail(detail, x, y);
+                }
+            });
+        }
+
+        @Override
+        public void onScanStateChanged(final boolean state) {
+            post(new Runnable() {
+                @Override
+                public void run() {
+                    handleScanStateChanged(state);
+                }
+            });
+        }
+    };
+
+    private final AnimatorListenerAdapter mHideGridContentWhenDone = new AnimatorListenerAdapter() {
+        public void onAnimationCancel(Animator animation) {
+            // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get
+            // called, this will avoid accidentally turning off the grid when we don't want to.
+            animation.removeListener(this);
+        };
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            // Only hide content if still in detail state.
+            if (mDetailAdapter != null) {
+                mQsPanel.setGridContentVisibility(false);
+            }
+        }
+    };
+
+    private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() {
+        public void onAnimationEnd(Animator animation) {
+            mDetailContent.removeAllViews();
+            setVisibility(View.INVISIBLE);
+            mClosingDetail = false;
+        };
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 1961860..53abe37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -16,12 +16,8 @@
 
 package com.android.systemui.qs;
 
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Handler;
@@ -29,16 +25,11 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile.DetailAdapter;
 import com.android.systemui.qs.customize.QSCustomizer;
@@ -60,21 +51,14 @@
 
     protected final Context mContext;
     protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
-    private final View mDetail;
-    private final ViewGroup mDetailContent;
-    private final TextView mDetailSettingsButton;
-    private final TextView mDetailDoneButton;
     protected final View mBrightnessView;
-    private final QSDetailClipper mClipper;
     private final H mHandler = new H();
 
     private int mPanelPaddingBottom;
     private int mBrightnessPaddingTop;
     private boolean mExpanded;
     private boolean mListening;
-    private boolean mClosingDetail;
 
-    private Record mDetailRecord;
     private Callback mCallback;
     private BrightnessController mBrightnessController;
     protected QSTileHost mHost;
@@ -86,6 +70,7 @@
     protected QSTileLayout mTileLayout;
 
     private QSCustomizer mCustomizePanel;
+    private Record mDetailRecord;
 
     public QSPanel(Context context) {
         this(context, null);
@@ -95,14 +80,6 @@
         super(context, attrs);
         mContext = context;
 
-        mDetail = LayoutInflater.from(context).inflate(R.layout.qs_detail, this, false);
-        mDetailContent = (ViewGroup) mDetail.findViewById(android.R.id.content);
-        mDetailSettingsButton = (TextView) mDetail.findViewById(android.R.id.button2);
-        mDetailDoneButton = (TextView) mDetail.findViewById(android.R.id.button1);
-        updateDetailText();
-        mDetail.setVisibility(GONE);
-        mDetail.setClickable(true);
-        addView(mDetail);
 
         mQsContainer = new LinearLayout(mContext);
         mQsContainer.setOrientation(LinearLayout.VERTICAL);
@@ -117,25 +94,31 @@
         mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
                 R.layout.qs_paged_tile_layout, mQsContainer, false);
         mQsContainer.addView((View) mTileLayout);
+        findViewById(android.R.id.edit).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(final View v) {
+                mHost.startRunnableDismissingKeyguard(new Runnable() {
+                    @Override
+                    public void run() {
+                        showEdit(v);
+                    }
+                });
+            }
+        });
 
         mFooter = new QSFooter(this, context);
         mQsContainer.addView(mFooter.getView());
 
-        mClipper = new QSDetailClipper(mDetail);
         updateResources();
 
         mBrightnessController = new BrightnessController(getContext(),
                 (ImageView) findViewById(R.id.brightness_icon),
                 (ToggleSlider) findViewById(R.id.brightness_slider));
 
-        mDetailDoneButton.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                announceForAccessibility(
-                        mContext.getString(R.string.accessibility_desc_quick_settings));
-                closeDetail();
-            }
-        });
+    }
+
+    public boolean isShowingCustomize() {
+        return mCustomizePanel != null && mCustomizePanel.isCustomizing();
     }
 
     @Override
@@ -178,11 +161,6 @@
         mCustomizePanel.setHost(mHost);
     }
 
-    private void updateDetailText() {
-        mDetailDoneButton.setText(R.string.quick_settings_done);
-        mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
-    }
-
     public void setBrightnessMirror(BrightnessMirrorController c) {
         super.onFinishInflate();
         ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider);
@@ -216,7 +194,6 @@
         if (mListening) {
             refreshAllTiles();
         }
-        updateDetailText();
         if (mTileLayout != null) {
             mTileLayout.updateResources();
         }
@@ -225,18 +202,6 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        FontSizeUtils.updateFontSize(mDetailDoneButton, R.dimen.qs_detail_button_text_size);
-        FontSizeUtils.updateFontSize(mDetailSettingsButton, R.dimen.qs_detail_button_text_size);
-
-        // We need to poke the detail views as well as they might not be attached to the view
-        // hierarchy but reused at a later point.
-        int count = mRecords.size();
-        for (int i = 0; i < count; i++) {
-            View detailView = mRecords.get(i).detailView;
-            if (detailView != null) {
-                detailView.dispatchConfigurationChanged(newConfig);
-            }
-        }
         mFooter.onConfigurationChanged();
     }
 
@@ -284,7 +249,7 @@
     public void showDetailAdapter(boolean show, DetailAdapter adapter, int[] locationInWindow) {
         int xInWindow = locationInWindow[0];
         int yInWindow = locationInWindow[1];
-        mDetail.getLocationInWindow(locationInWindow);
+        ((View) getParent()).getLocationInWindow(locationInWindow);
 
         Record r = new Record();
         r.detailAdapter = adapter;
@@ -309,9 +274,6 @@
         for (QSTile<?> tile : tiles) {
             addTile(tile);
         }
-        if (isShowingDetail()) {
-            mDetail.bringToFront();
-        }
     }
 
     private void drawTile(TileRecord r, QSTile.State state) {
@@ -329,9 +291,7 @@
         final QSTile.Callback callback = new QSTile.Callback() {
             @Override
             public void onStateChanged(QSTile.State state) {
-                if (!r.openingDetail) {
-                    drawTile(r, state);
-                }
+                drawTile(r, state);
             }
 
             @Override
@@ -369,19 +329,7 @@
         final View.OnLongClickListener longClick = new View.OnLongClickListener() {
             @Override
             public boolean onLongClick(View v) {
-                if (mCustomizePanel != null) {
-                    if (!mCustomizePanel.isCustomizing()) {
-                        int[] loc = new int[2];
-                        getLocationInWindow(loc);
-                        int x = r.tileView.getLeft() + r.tileView.getWidth() / 2 + loc[0];
-                        int y = r.tileView.getTop() + mTileLayout.getOffsetTop(r)
-                                + r.tileView.getHeight() / 2 + loc[1];
-                        mCustomizePanel.show(x, y);
-                    }
-                } else {
-                    r.tile.longClick();
-                }
-                return true;
+                return false;
             }
         };
         r.tileView.init(click, longClick);
@@ -395,13 +343,27 @@
         }
     }
 
-    protected void onTileClick(QSTile<?> tile) {
-        tile.click();
+
+    private void showEdit(final View v) {
+        v.post(new Runnable() {
+            @Override
+            public void run() {
+                if (mCustomizePanel != null) {
+                    if (!mCustomizePanel.isCustomizing()) {
+                        int[] loc = new int[2];
+                        v.getLocationInWindow(loc);
+                        int x = loc[0];
+                        int y = loc[1];
+                        mCustomizePanel.show(x, y);
+                    }
+                }
+
+            }
+        });
     }
 
-    public boolean isShowingDetail() {
-        return mDetailRecord != null
-                || (mCustomizePanel != null && mCustomizePanel.isCustomizing());
+    protected void onTileClick(QSTile<?> tile) {
+        tile.click();
     }
 
     public void closeDetail() {
@@ -413,10 +375,6 @@
         showDetail(false, mDetailRecord);
     }
 
-    public boolean isClosingDetail() {
-        return mClosingDetail;
-    }
-
     public int getGridHeight() {
         return mQsContainer.getMeasuredHeight();
     }
@@ -447,58 +405,25 @@
         }
         r.tile.setDetailListening(show);
         int x = r.tileView.getLeft() + r.tileView.getWidth() / 2;
-        int y = r.tileView.getTop() + mTileLayout.getOffsetTop(r) + r.tileView.getHeight() / 2;
+        int y = r.tileView.getTop() + mTileLayout.getOffsetTop(r) + r.tileView.getHeight() / 2
+                + getTop();
         handleShowDetailImpl(r, show, x, y);
     }
 
     private void handleShowDetailImpl(Record r, boolean show, int x, int y) {
-        boolean visibleDiff = (mDetailRecord != null) != show;
-        if (!visibleDiff && mDetailRecord == r) return;  // already in right state
-        DetailAdapter detailAdapter = null;
-        AnimatorListener listener = null;
-        if (show) {
-            detailAdapter = r.detailAdapter;
-            r.detailView = detailAdapter.createDetailView(mContext, r.detailView, mDetailContent);
-            if (r.detailView == null) throw new IllegalStateException("Must return detail view");
-
-            final Intent settingsIntent = detailAdapter.getSettingsIntent();
-            mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
-            mDetailSettingsButton.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mHost.startActivityDismissingKeyguard(settingsIntent);
-                }
-            });
-
-            mDetailContent.removeAllViews();
-            mDetail.bringToFront();
-            mDetailContent.addView(r.detailView);
-            MetricsLogger.visible(mContext, detailAdapter.getMetricsCategory());
-            announceForAccessibility(mContext.getString(
-                    R.string.accessibility_quick_settings_detail,
-                    detailAdapter.getTitle()));
-            setDetailRecord(r);
-            listener = mHideGridContentWhenDone;
-            if (r instanceof TileRecord && visibleDiff) {
-                ((TileRecord) r).openingDetail = true;
-            }
-        } else {
-            if (mDetailRecord != null) {
-                MetricsLogger.hidden(mContext, mDetailRecord.detailAdapter.getMetricsCategory());
-            }
-            mClosingDetail = true;
-            setGridContentVisibility(true);
-            listener = mTeardownDetailWhenDone;
-            fireScanStateChanged(false);
-        }
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-        fireShowingDetail(show ? detailAdapter : null);
-        if (visibleDiff) {
-            mClipper.animateCircularClip(x, y, show, listener);
-        }
+        setDetailRecord(show ? r : null);
+        fireShowingDetail(show ? r.detailAdapter : null, x, y);
     }
 
-    private void setGridContentVisibility(boolean visible) {
+    private void setDetailRecord(Record r) {
+        if (r == mDetailRecord) return;
+        mDetailRecord = r;
+        final boolean scanState = mDetailRecord instanceof TileRecord
+                && ((TileRecord) mDetailRecord).scanState;
+        fireScanStateChanged(scanState);
+    }
+
+    void setGridContentVisibility(boolean visible) {
         int newVis = visible ? VISIBLE : INVISIBLE;
         mQsContainer.setVisibility(newVis);
         if (mGridContentVisible != visible) {
@@ -514,9 +439,9 @@
         }
     }
 
-    private void fireShowingDetail(QSTile.DetailAdapter detail) {
+    private void fireShowingDetail(DetailAdapter detail, int x, int y) {
         if (mCallback != null) {
-            mCallback.onShowingDetail(detail);
+            mCallback.onShowingDetail(detail, x, y);
         }
     }
 
@@ -532,14 +457,6 @@
         }
     }
 
-    private void setDetailRecord(Record r) {
-        if (r == mDetailRecord) return;
-        mDetailRecord = r;
-        final boolean scanState = mDetailRecord instanceof TileRecord
-                && ((TileRecord) mDetailRecord).scanState;
-        fireScanStateChanged(scanState);
-    }
-
     public void clickTile(ComponentName tile) {
         final String spec = CustomTile.toSpec(tile);
         final int N = mRecords.size();
@@ -563,7 +480,6 @@
     }
 
     protected static class Record {
-        View detailView;
         DetailAdapter detailAdapter;
         int x;
         int y;
@@ -573,45 +489,10 @@
         public QSTile<?> tile;
         public QSTileBaseView tileView;
         public boolean scanState;
-        public boolean openingDetail;
     }
 
-    private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() {
-        public void onAnimationEnd(Animator animation) {
-            mDetailContent.removeAllViews();
-            setDetailRecord(null);
-            mClosingDetail = false;
-        };
-    };
-
-    private final AnimatorListenerAdapter mHideGridContentWhenDone = new AnimatorListenerAdapter() {
-        public void onAnimationCancel(Animator animation) {
-            // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get
-            // called, this will avoid accidentally turning off the grid when we don't want to.
-            animation.removeListener(this);
-            redrawTile();
-        };
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            // Only hide content if still in detail state.
-            if (mDetailRecord != null) {
-                setGridContentVisibility(false);
-                redrawTile();
-            }
-        }
-
-        private void redrawTile() {
-            if (mDetailRecord instanceof TileRecord) {
-                final TileRecord tileRecord = (TileRecord) mDetailRecord;
-                tileRecord.openingDetail = false;
-                drawTile(tileRecord, tileRecord.tile.getState());
-            }
-        }
-    };
-
     public interface Callback {
-        void onShowingDetail(QSTile.DetailAdapter detail);
+        void onShowingDetail(DetailAdapter detail, int x, int y);
         void onToggleStateChanged(boolean state);
         void onScanStateChanged(boolean state);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index edcccac..81e1581 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -90,16 +90,20 @@
     }
 
     public void show(int x, int y) {
-        isShown = true;
-        mPhoneStatusBar.getStatusBarWindow().addView(this);
-        setTileSpecs();
-        mClipper.animateCircularClip(x, y, true, this);
-        new TileQueryHelper(mContext, mHost).setListener(mTileAdapter);
+        if (!isShown) {
+            isShown = true;
+            mPhoneStatusBar.getStatusBarWindow().addView(this);
+            setTileSpecs();
+            mClipper.animateCircularClip(x, y, true, this);
+            new TileQueryHelper(mContext, mHost).setListener(mTileAdapter);
+        }
     }
 
     public void hide(int x, int y) {
-        isShown = false;
-        mClipper.animateCircularClip(x, y, false, this);
+        if (isShown) {
+            isShown = false;
+            mClipper.animateCircularClip(x, y, false, this);
+        }
     }
 
     public boolean isCustomizing() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 2a10c0b..5c34ceb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -55,7 +55,7 @@
     private void addSystemTiles(QSTileHost host) {
         boolean hasColorMod = host.getDisplayController().isEnabled();
         String possible = mContext.getString(R.string.quick_settings_tiles_default)
-                + ",hotspot,inversion,saver,work" + (hasColorMod ? ",colors" : "");
+                + ",hotspot,inversion,saver,work,cast" + (hasColorMod ? ",colors" : "");
         String[] possibleTiles = possible.split(",");
         final Handler qsHandler = new Handler(host.getLooper());
         final Handler mainHandler = new Handler(Looper.getMainLooper());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
index 72cdf18..6a9d826 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -19,15 +19,18 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.RelativeSizeSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Checkable;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.BatteryInfo;
+import com.android.settingslib.graph.UsageView;
 import com.android.systemui.BatteryMeterDrawable;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile;
@@ -161,29 +164,45 @@
                 BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
                     @Override
                     public void onBatteryInfoLoaded(BatteryInfo info) {
-                        if (mCurrentView != null && mCharging) {
-                            ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
-                                    info.mChargeLabelString);
+                        if (mCurrentView != null) {
+                            bindBatteryInfo(info);
                         }
                     }
                 });
-                ((TextView) mCurrentView.findViewById(android.R.id.summary)).setText(
+                ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
                         R.string.battery_detail_charging_summary);
-                mCurrentView.setClickable(false);
                 mCurrentView.findViewById(android.R.id.icon).setVisibility(View.INVISIBLE);
-                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.INVISIBLE);
+                mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.GONE);
+                mCurrentView.findViewById(R.id.switch_container).setClickable(false);
             } else {
                 ((TextView) mCurrentView.findViewById(android.R.id.title)).setText(
                         R.string.battery_detail_switch_title);
                 ((TextView) mCurrentView.findViewById(android.R.id.summary)).setText(
                         R.string.battery_detail_switch_summary);
-                mCurrentView.setClickable(true);
                 mCurrentView.findViewById(android.R.id.icon).setVisibility(View.VISIBLE);
                 mCurrentView.findViewById(android.R.id.toggle).setVisibility(View.VISIBLE);
-                mCurrentView.setOnClickListener(this);
+                mCurrentView.findViewById(R.id.switch_container).setClickable(true);
+                mCurrentView.findViewById(R.id.switch_container).setOnClickListener(this);
             }
         }
 
+        private void bindBatteryInfo(BatteryInfo info) {
+            SpannableStringBuilder builder = new SpannableStringBuilder();
+            builder.append(info.batteryPercentString, new RelativeSizeSpan(2),
+                    Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+            if (info.remainingLabel != null) {
+                if (mContext.getResources().getBoolean(R.bool.quick_settings_wide)) {
+                    builder.append(' ');
+                } else {
+                    builder.append('\n');
+                }
+                builder.append(info.remainingLabel);
+            }
+            ((TextView) mCurrentView.findViewById(R.id.charge_and_estimation)).setText(builder);
+
+            info.bindHistory((UsageView) mCurrentView.findViewById(R.id.battery_usage));
+        }
+
         @Override
         public void onClick(View v) {
             mBatteryController.setPowerSaveMode(!mPowerSave);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index e4fd31d..f5ae351 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -31,10 +31,13 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.EventLog;
 import android.util.Log;
 import android.view.Display;
 import android.view.View;
 
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SystemUI;
 import com.android.systemui.recents.events.EventBus;
@@ -83,20 +86,23 @@
     private int mDraggingInRecentsCurrentUser;
 
     // Only For system user, this is the callbacks instance we return to each secondary user
-    private RecentsSystemUser mSystemUserCallbacks;
+    private RecentsSystemUser mSystemToUserCallbacks;
 
     // Only for secondary users, this is the callbacks instance provided by the system user to make
     // calls back
-    private IRecentsSystemUserCallbacks mCallbacksToSystemUser;
+    private IRecentsSystemUserCallbacks mUserToSystemCallbacks;
 
     // The set of runnables to run after binding to the system user's service.
     private final ArrayList<Runnable> mOnConnectRunnables = new ArrayList<>();
 
     // Only for secondary users, this is the death handler for the binder from the system user
-    private final IBinder.DeathRecipient mCallbacksToSystemUserDeathRcpt = new IBinder.DeathRecipient() {
+    private final IBinder.DeathRecipient mUserToSystemCallbacksDeathRcpt = new IBinder.DeathRecipient() {
         @Override
         public void binderDied() {
-            mCallbacksToSystemUser = null;
+            mUserToSystemCallbacks = null;
+            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
+                    EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_UNBOUND,
+                    sSystemServicesProxy.getProcessUser());
 
             // Retry after a fixed duration
             mHandler.postDelayed(new Runnable() {
@@ -109,16 +115,19 @@
     };
 
     // Only for secondary users, this is the service connection we use to connect to the system user
-    private final ServiceConnection mServiceConnectionToSystemUser = new ServiceConnection() {
+    private final ServiceConnection mUserToSystemServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (service != null) {
-                mCallbacksToSystemUser = IRecentsSystemUserCallbacks.Stub.asInterface(
+                mUserToSystemCallbacks = IRecentsSystemUserCallbacks.Stub.asInterface(
                         service);
+                EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
+                        EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_SYSTEM_BOUND,
+                        sSystemServicesProxy.getProcessUser());
 
                 // Listen for system user's death, so that we can reconnect later
                 try {
-                    service.linkToDeath(mCallbacksToSystemUserDeathRcpt, 0);
+                    service.linkToDeath(mUserToSystemCallbacksDeathRcpt, 0);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Lost connection to (System) SystemUI", e);
                 }
@@ -142,7 +151,7 @@
      * Returns the callbacks interface that non-system users can call.
      */
     public IBinder getSystemUserCallbacks() {
-        return mSystemUserCallbacks;
+        return mSystemToUserCallbacks;
     }
 
     public static RecentsTaskLoader getTaskLoader() {
@@ -190,7 +199,7 @@
         if (sSystemServicesProxy.isSystemUser(processUser)) {
             // For the system user, initialize an instance of the interface that we can pass to the
             // secondary user
-            mSystemUserCallbacks = new RecentsSystemUser(mContext, mImpl);
+            mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
         } else {
             // For the secondary user, bind to the primary user's service to get a persistent
             // interface to register its implementation and to later update its state
@@ -224,9 +233,9 @@
             mImpl.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
                     true /* animate */, false /* reloadTasks */);
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.showRecents(triggeredFromAltTab, false /* draggingInRecents */,
@@ -260,9 +269,9 @@
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
@@ -295,9 +304,9 @@
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.toggleRecents();
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.toggleRecents();
@@ -326,9 +335,9 @@
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.preloadRecents();
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.preloadRecents();
@@ -354,9 +363,9 @@
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.cancelPreloadingRecents();
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.cancelPreloadingRecents();
@@ -387,9 +396,9 @@
             if (sSystemServicesProxy.isSystemUser(currentUser)) {
                 mImpl.dockTopTask(topTask.id, dragMode, stackCreateMode, initialBounds);
             } else {
-                if (mSystemUserCallbacks != null) {
+                if (mSystemToUserCallbacks != null) {
                     IRecentsNonSystemUserCallbacks callbacks =
-                            mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                            mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                     if (callbacks != null) {
                         try {
                             callbacks.dockTopTask(topTask.id, dragMode, stackCreateMode,
@@ -413,9 +422,9 @@
         if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
             mImpl.onDraggingInRecents(distanceFromTop);
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
                                 mDraggingInRecentsCurrentUser);
                 if (callbacks != null) {
                     try {
@@ -436,9 +445,9 @@
         if (sSystemServicesProxy.isSystemUser(mDraggingInRecentsCurrentUser)) {
             mImpl.onDraggingInRecentsEnded(velocity);
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(
                                 mDraggingInRecentsCurrentUser);
                 if (callbacks != null) {
                     try {
@@ -484,9 +493,9 @@
         if (sSystemServicesProxy.isSystemUser(currentUser)) {
             mImpl.onConfigurationChanged();
         } else {
-            if (mSystemUserCallbacks != null) {
+            if (mSystemToUserCallbacks != null) {
                 IRecentsNonSystemUserCallbacks callbacks =
-                        mSystemUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
+                        mSystemToUserCallbacks.getNonSystemUserRecentsForUser(currentUser);
                 if (callbacks != null) {
                     try {
                         callbacks.onConfigurationChanged();
@@ -512,7 +521,7 @@
                 @Override
                 public void run() {
                     try {
-                        mCallbacksToSystemUser.updateRecentsVisibility(event.visible);
+                        mUserToSystemCallbacks.updateRecentsVisibility(event.visible);
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -533,7 +542,7 @@
                 @Override
                 public void run() {
                     try {
-                        mCallbacksToSystemUser.startScreenPinning();
+                        mUserToSystemCallbacks.startScreenPinning();
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -549,7 +558,7 @@
                 @Override
                 public void run() {
                     try {
-                        mCallbacksToSystemUser.sendRecentsDrawnEvent();
+                        mUserToSystemCallbacks.sendRecentsDrawnEvent();
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -565,7 +574,7 @@
                 @Override
                 public void run() {
                     try {
-                        mCallbacksToSystemUser.sendDockingTopTaskEvent(event.dragMode);
+                        mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode);
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -581,7 +590,7 @@
                 @Override
                 public void run() {
                     try {
-                        mCallbacksToSystemUser.sendLaunchRecentsEvent();
+                        mUserToSystemCallbacks.sendLaunchRecentsEvent();
                     } catch (RemoteException e) {
                         Log.e(TAG, "Callback failed", e);
                     }
@@ -599,7 +608,7 @@
             @Override
             public void run() {
                 try {
-                    mCallbacksToSystemUser.registerNonSystemUserCallbacks(
+                    mUserToSystemCallbacks.registerNonSystemUserCallbacks(
                             new RecentsImplProxy(mImpl), processUser);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to register", e);
@@ -614,11 +623,14 @@
      */
     private void postToSystemUser(final Runnable onConnectRunnable) {
         mOnConnectRunnables.add(onConnectRunnable);
-        if (mCallbacksToSystemUser == null) {
+        if (mUserToSystemCallbacks == null) {
             Intent systemUserServiceIntent = new Intent();
             systemUserServiceIntent.setClass(mContext, RecentsSystemUserService.class);
             boolean bound = mContext.bindServiceAsUser(systemUserServiceIntent,
-                    mServiceConnectionToSystemUser, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+                    mUserToSystemServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
+                    EventLogConstants.SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE,
+                    sSystemServicesProxy.getProcessUser());
             if (!bound) {
                 // Retry after a fixed duration
                 mHandler.postDelayed(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 3f482c8..c2a6108 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -205,7 +205,7 @@
                 ? stack.indexOfStackTask(launchTarget)
                 : 0;
         boolean hasNavBarScrim = (taskCount > 0) && !config.hasTransposedNavBar;
-        boolean animateNavBarScrim = true;
+        boolean animateNavBarScrim = !launchState.launchedWhileDocking;
         mScrimViews.prepareEnterRecentsAnimation(hasNavBarScrim, animateNavBarScrim);
 
         // Keep track of whether we launched from the nav bar button or via alt-tab
@@ -230,7 +230,7 @@
      * Dismisses the history view back into the stack view.
      */
     boolean dismissHistory() {
-        if (mRecentsView.isHistoryVisible()) {
+        if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
             EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
             return true;
         }
@@ -240,11 +240,11 @@
     /**
      * Dismisses recents if we are already visible and the intent is to toggle the recents view.
      */
-    boolean dismissRecentsToFocusedTask() {
+    boolean dismissRecentsToFocusedTask(int logCategory) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
             // If we have a focused Task, launch that Task now
-            if (mRecentsView.launchFocusedTask()) return true;
+            if (mRecentsView.launchFocusedTask(logCategory)) return true;
         }
         return false;
     }
@@ -270,7 +270,7 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
             // If we have a focused Task, launch that Task now
-            if (mRecentsView.launchFocusedTask()) return true;
+            if (mRecentsView.launchFocusedTask(0 /* logCategory */)) return true;
             // If none of the other cases apply, then just go Home
             dismissRecentsToHome(true /* animateTaskViews */);
             return true;
@@ -360,7 +360,7 @@
         mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
             @Override
             public void run() {
-                dismissRecentsToFocusedTask();
+                dismissRecentsToFocusedTask(MetricsEvent.OVERVIEW_SELECT_TIMEOUT);
             }
         });
 
@@ -447,7 +447,7 @@
 
         // Reset some states
         mIgnoreAltTabRelease = false;
-        if (mRecentsView.isHistoryVisible()) {
+        if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
             EventBus.getDefault().send(new HideHistoryEvent(false /* animate */));
         }
 
@@ -460,13 +460,7 @@
         // wait on the system to send a signal that was never queued.
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
-        launchState.launchedFromHome = false;
-        launchState.launchedFromSearchHome = false;
-        launchState.launchedFromAppWithThumbnail = false;
-        launchState.launchedToTaskId = -1;
-        launchState.launchedWithAltTab = false;
-        launchState.launchedHasConfigurationChanged = false;
-        launchState.launchedViaDragGesture = false;
+        launchState.reset();
 
         MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
     }
@@ -509,13 +503,16 @@
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-        outState.putBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, mRecentsView.isHistoryVisible());
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            outState.putBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, mRecentsView.isHistoryVisible());
+        }
     }
 
     @Override
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
-        if (savedInstanceState.getBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, false)) {
+        if (RecentsDebugFlags.Static.EnableHistory &&
+                savedInstanceState.getBoolean(KEY_SAVED_STATE_HISTORY_VISIBLE, false)) {
             EventBus.getDefault().send(new ShowHistoryEvent());
         }
     }
@@ -609,7 +606,7 @@
     /**** EventBus events ****/
 
     public final void onBusEvent(ToggleRecentsEvent event) {
-        if (!dismissHistory()) {
+        if (!RecentsDebugFlags.Static.EnableHistory || !dismissHistory()) {
             RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
             if (launchState.launchedFromHome) {
                 dismissRecentsToHome(true /* animateTaskViews */);
@@ -620,7 +617,7 @@
     }
 
     public final void onBusEvent(IterateRecentsEvent event) {
-        if (!dismissHistory()) {
+        if (!RecentsDebugFlags.Static.EnableHistory || !dismissHistory()) {
             final RecentsDebugFlags debugFlags = Recents.getDebugFlags();
 
             // Start dozing after the recents button is clicked
@@ -640,7 +637,7 @@
             // Focus the next task
             EventBus.getDefault().send(new FocusNextTaskViewEvent(timerIndicatorDuration));
 
-            MetricsLogger.action(this, MetricsEvent.ACTION_OVERVIEW_PAGE);
+            MetricsLogger.action(this, MetricsEvent.OVERVIEW_PAGE);
         }
     }
 
@@ -657,7 +654,7 @@
             }
         } else if (event.triggeredFromHomeKey) {
             // Otherwise, dismiss Recents to Home
-            if (mRecentsView.isHistoryVisible()) {
+            if (RecentsDebugFlags.Static.EnableHistory && mRecentsView.isHistoryVisible()) {
                 // If the history view is visible, then just cross-fade home
                 ActivityOptions opts = ActivityOptions.makeCustomAnimation(RecentsActivity.this,
                                 R.anim.recents_to_launcher_enter,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index 177e841..aa1437b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -34,10 +34,22 @@
     public boolean launchedReuseTaskStackViews;
     public boolean launchedHasConfigurationChanged;
     public boolean launchedViaDragGesture;
+    public boolean launchedWhileDocking;
     public int launchedToTaskId;
     public int launchedNumVisibleTasks;
     public int launchedNumVisibleThumbnails;
 
+    public void reset() {
+        launchedFromHome = false;
+        launchedFromSearchHome = false;
+        launchedFromAppWithThumbnail = false;
+        launchedToTaskId = -1;
+        launchedWithAltTab = false;
+        launchedHasConfigurationChanged = false;
+        launchedViaDragGesture = false;
+        launchedWhileDocking = false;
+    }
+
     /** Called when the configuration has changed, and we want to reset any configuration specific
      * members. */
     public void updateOnConfigurationChange() {
@@ -46,6 +58,7 @@
         // Set this flag to indicate that the configuration has changed since Recents last launched
         launchedHasConfigurationChanged = true;
         launchedViaDragGesture = false;
+        launchedWhileDocking = false;
     }
 
     /**
@@ -53,17 +66,18 @@
      */
     public int getInitialFocusTaskIndex(int numTasks) {
         RecentsDebugFlags debugFlags = Recents.getDebugFlags();
+        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
         if (launchedFromAppWithThumbnail) {
-            if (debugFlags.isFastToggleRecentsEnabled()) {
+            if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled()) {
                 // If fast toggling, focus the front most task so that the next tap will focus the
                 // N-1 task
                 return numTasks - 1;
             }
 
             // If coming from another app, focus the next task
-            return numTasks - 2;
+            return Math.max(0, numTasks - 2);
         } else {
-            if (debugFlags.isFastToggleRecentsEnabled()) {
+            if (!launchState.launchedWithAltTab && debugFlags.isFastToggleRecentsEnabled()) {
                 // If fast toggling, defer focusing until the next tap (which will automatically
                 // focus the front most task)
                 return -1;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index fc14758..cd64323 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -37,6 +37,8 @@
         public static final boolean DisableBackgroundCache = false;
         // Enables the task affiliations
         public static final boolean EnableAffiliatedTaskGroups = true;
+        // Enables the history
+        public static final boolean EnableHistory = false;
         // Overrides the Tuner flags and enables the fast toggle and timeout
         public static final boolean EnableFastToggleTimeoutOverride = true;
 
@@ -52,11 +54,9 @@
         public static final int MockTaskGroupsTaskCount = 12;
     }
 
-    private static final String KEY_FAST_TOGGLE = "overview_fast_toggle_via_button";
-    private static final String KEY_INITIAL_STATE_PAGING = "overview_initial_state_paging";
+    private static final String KEY_DISABLE_FAST_TOGGLE = "overview_disable_fast_toggle_via_button";
 
-    private boolean mFastToggleRecents;
-    private boolean mInitialStatePaging;
+    private boolean mDisableFastToggleRecents;
 
     /**
      * We read the prefs once when we start the activity, then update them as the tuner changes
@@ -65,7 +65,7 @@
     public RecentsDebugFlags(Context context) {
         // Register all our flags, this will also call onTuningChanged() for each key, which will
         // initialize the current state of each flag
-        TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_INITIAL_STATE_PAGING);
+        TunerService.get(context).addTunable(this, KEY_DISABLE_FAST_TOGGLE);
     }
 
     /**
@@ -74,32 +74,21 @@
     public boolean isFastToggleRecentsEnabled() {
         // These checks EnableFastToggleTimeoutOverride
         SystemServicesProxy ssp = Recents.getSystemServices();
-        if (ssp.hasFreeformWorkspaceSupport() || ssp.hasDockedTask() ||
-                ssp.isTouchExplorationEnabled()) {
+        if (mDisableFastToggleRecents || ssp.hasFreeformWorkspaceSupport() || ssp.hasDockedTask()
+                || ssp.isTouchExplorationEnabled()) {
             return false;
         }
         if (Static.EnableFastToggleTimeoutOverride) {
             return true;
         }
-        return mFastToggleRecents;
-    }
-
-    /**
-     * @return whether the initial stack state is paging.
-     */
-    public boolean isInitialStatePaging() {
-        return mInitialStatePaging;
+        return true;
     }
 
     @Override
     public void onTuningChanged(String key, String newValue) {
         switch (key) {
-            case KEY_FAST_TOGGLE:
-                mFastToggleRecents = (newValue != null) &&
-                        (Integer.parseInt(newValue) != 0);
-                break;
-            case KEY_INITIAL_STATE_PAGING:
-                mInitialStatePaging = (newValue != null) &&
+            case KEY_DISABLE_FAST_TOGGLE:
+                mDisableFastToggleRecents = (newValue != null) &&
                         (Integer.parseInt(newValue) != 0);
                 break;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index dd7b7c1..8de964b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -124,6 +124,10 @@
         public void onPinnedActivityRestartAttempt() {
         }
 
+        @Override
+        public void onPinnedStackAnimationEnded() {
+        }
+
         /** Preloads the next task */
         public void run() {
             RecentsConfiguration config = Recents.getConfiguration();
@@ -161,6 +165,7 @@
     boolean mCanReuseTaskStackViews = true;
     boolean mDraggingInRecents;
     boolean mReloadTasks;
+    boolean mLaunchedWhileDocking;
 
     // Task launching
     Rect mSearchBarBounds = new Rect();
@@ -270,10 +275,10 @@
     }
 
     public void showRecents(boolean triggeredFromAltTab, boolean draggingInRecents,
-            boolean animate, boolean reloadTasks) {
+            boolean animate, boolean launchedWhileDockingTask) {
         mTriggeredFromAltTab = triggeredFromAltTab;
         mDraggingInRecents = draggingInRecents;
-        mReloadTasks = reloadTasks;
+        mLaunchedWhileDocking = launchedWhileDockingTask;
         if (mFastAltTabTrigger.hasTriggered()) {
             // We are calling this from the doze trigger, so just fall through to show Recents
             mFastAltTabTrigger.resetTrigger();
@@ -338,6 +343,7 @@
         }
 
         mDraggingInRecents = false;
+        mLaunchedWhileDocking = false;
         mTriggeredFromAltTab = false;
 
         try {
@@ -400,9 +406,9 @@
         SystemServicesProxy ssp = Recents.getSystemServices();
         ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask();
         MutableBoolean topTaskHome = new MutableBoolean(true);
-        RecentsTaskLoader loader = Recents.getTaskLoader();
-        sInstanceLoadPlan = loader.createLoadPlan(mContext);
         if (topTask != null && !ssp.isRecentsTopMost(topTask, topTaskHome)) {
+            RecentsTaskLoader loader = Recents.getTaskLoader();
+            sInstanceLoadPlan = loader.createLoadPlan(mContext);
             sInstanceLoadPlan.preloadRawTasks(topTaskHome.value);
             loader.preloadTasks(sInstanceLoadPlan, topTask.id, topTaskHome.value);
             TaskStack stack = sInstanceLoadPlan.getTaskStack();
@@ -831,11 +837,13 @@
      * Draws the header of a task used for the window animation into a bitmap.
      */
     private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
         if (toTransform != null && toTask.key != null) {
             Bitmap thumbnail;
             synchronized (mHeaderBarLock) {
                 int toHeaderWidth = (int) toTransform.rect.width();
                 int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale);
+                boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
                 mHeaderBar.onTaskViewSizeChanged((int) toTransform.rect.width(),
                         (int) toTransform.rect.height());
                 thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight,
@@ -845,7 +853,8 @@
                 } else {
                     Canvas c = new Canvas(thumbnail);
                     c.scale(toTransform.scale, toTransform.scale);
-                    mHeaderBar.rebindToTask(toTask, false /* touchExplorationEnabled */);
+                    mHeaderBar.rebindToTask(toTask, false /* touchExplorationEnabled */,
+                            disabledInSafeMode);
                     mHeaderBar.draw(c);
                     c.setBitmap(null);
                 }
@@ -865,11 +874,11 @@
         // In the case where alt-tab is triggered, we never get a preloadRecents() call, so we
         // should always preload the tasks now. If we are dragging in recents, reload them as
         // the stacks might have changed.
-        if (mReloadTasks || mTriggeredFromAltTab ||sInstanceLoadPlan == null) {
+        if (mLaunchedWhileDocking || mTriggeredFromAltTab ||sInstanceLoadPlan == null) {
             // Create a new load plan if preloadRecents() was never triggered
             sInstanceLoadPlan = loader.createLoadPlan(mContext);
         }
-        if (mReloadTasks || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
+        if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
             loader.preloadTasks(sInstanceLoadPlan, topTask.id, isTopTaskHome);
         }
         TaskStack stack = sInstanceLoadPlan.getTaskStack();
@@ -957,6 +966,7 @@
         launchState.launchedNumVisibleThumbnails = vr.numVisibleThumbnails;
         launchState.launchedHasConfigurationChanged = false;
         launchState.launchedViaDragGesture = mDraggingInRecents;
+        launchState.launchedWhileDocking = mLaunchedWhileDocking;
 
         Intent intent = new Intent();
         intent.setClassName(RECENTS_PACKAGE, mRecentsIntentActivityName);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
index ae0051c..f8000b8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java
@@ -19,9 +19,12 @@
 import android.content.Context;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.activity.DockingTopTaskEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
@@ -46,7 +49,8 @@
     }
 
     @Override
-    public void registerNonSystemUserCallbacks(final IBinder nonSystemUserCallbacks, int userId) {
+    public void registerNonSystemUserCallbacks(final IBinder nonSystemUserCallbacks,
+            final int userId) {
         try {
             final IRecentsNonSystemUserCallbacks callback =
                     IRecentsNonSystemUserCallbacks.Stub.asInterface(nonSystemUserCallbacks);
@@ -54,9 +58,14 @@
                 @Override
                 public void binderDied() {
                     mNonSystemUserRecents.removeAt(mNonSystemUserRecents.indexOfValue(callback));
+                    EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
+                            EventLogConstants.SYSUI_RECENTS_CONNECTION_SYSTEM_UNREGISTER_USER,
+                            userId);
                 }
             }, 0);
             mNonSystemUserRecents.put(userId, callback);
+            EventLog.writeEvent(EventLogTags.SYSUI_RECENTS_CONNECTION,
+                    EventLogConstants.SYSUI_RECENTS_CONNECTION_SYSTEM_REGISTER_USER, userId);
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to register NonSystemUserCallbacks", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
index 5eeda72..d7b9b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java
@@ -161,7 +161,7 @@
             ssp.startActivityFromRecents(v.getContext(), task.key.id, task.title,
                     ActivityOptions.makeBasic());
 
-            MetricsLogger.action(v.getContext(), MetricsEvent.ACTION_OVERVIEW_SELECT,
+            MetricsLogger.action(v.getContext(), MetricsEvent.OVERVIEW_SELECT,
                     task.key.getComponent().toString());
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java
index acad0ea..3d1ea8e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryItemTouchCallbacks.java
@@ -21,6 +21,7 @@
 import android.support.v7.widget.helper.ItemTouchHelper;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
@@ -72,6 +73,8 @@
             // Keep track of deletions by swiping within history
             MetricsLogger.histogram(mContext, "overview_task_dismissed_source",
                     Constants.Metrics.DismissSourceHistorySwipeGesture);
+            MetricsLogger.action(mContext, MetricsEvent.OVERVIEW_DISMISS,
+                    taskRow.task.key.getComponent().toString());
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
index 843adc1..3c4adb2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java
@@ -186,6 +186,7 @@
         mRecyclerView = (RecyclerView) findViewById(R.id.list);
         mRecyclerView.setAdapter(mAdapter);
         mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+        mRecyclerView.getItemAnimator().setRemoveDuration(100);
         ItemTouchHelper touchHelper = new ItemTouchHelper(mItemTouchHandler);
         touchHelper.attachToRecyclerView(mRecyclerView);
     }
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 244c0df..95aa10f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/DozeTrigger.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents.misc;
 
 import android.os.Handler;
+import android.view.ViewDebug;
 
 /**
  * A dozer is a class that fires a trigger after it falls asleep.
@@ -26,8 +27,11 @@
 
     Handler mHandler;
 
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mIsDozing;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mHasTriggered;
+    @ViewDebug.ExportedProperty(category="recents")
     int mDozeDurationMilliseconds;
     Runnable mOnSleepRunnable;
 
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 22ab794..8b4474f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -112,6 +112,8 @@
     Display mDisplay;
     String mRecentsPackage;
     ComponentName mAssistComponent;
+
+    boolean mIsSafeMode;
     boolean mHasFreeformWorkspaceSupport;
 
     Bitmap mDummyIcon;
@@ -137,6 +139,7 @@
                 mPm.hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT) ||
                         Settings.Global.getInt(context.getContentResolver(),
                                 DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
+        mIsSafeMode = mPm.isSafeMode();
 
         // Get the dummy thumbnail width/heights
         Resources res = context.getResources();
@@ -187,7 +190,8 @@
                 rti.firstActiveTime = rti.lastActiveTime = i;
                 if (i % 2 == 0) {
                     rti.taskDescription = new ActivityManager.TaskDescription(description,
-                        Bitmap.createBitmap(mDummyIcon),
+                        Bitmap.createBitmap(mDummyIcon), null,
+                        0xFF000000 | (0xFFFFFF & new Random().nextInt()),
                         0xFF000000 | (0xFFFFFF & new Random().nextInt()));
                 } else {
                     rti.taskDescription = new ActivityManager.TaskDescription();
@@ -260,6 +264,13 @@
         return mHasFreeformWorkspaceSupport;
     }
 
+    /**
+     * Returns whether this device is in the safe mode.
+     */
+    public boolean isInSafeMode() {
+        return mIsSafeMode;
+    }
+
     /** Returns whether the recents is currently running */
     public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
             MutableBoolean isHomeTopMost) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
index 4deea54..e86b92d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java
@@ -17,6 +17,8 @@
 package com.android.systemui.recents.misc;
 
 import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.annotation.FloatRange;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -30,6 +32,7 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.views.TaskViewTransform;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -62,6 +65,8 @@
                 }
             };
 
+    public static final RectFEvaluator RECTF_EVALUATOR = new RectFEvaluator();
+
     /**
      * @return the first parent walking up the view hierarchy that has the given class type.
      *
@@ -100,6 +105,46 @@
         return setOut;
     }
 
+    /**
+     * @return the clamped {@param value} between the provided {@param min} and {@param max}.
+     */
+    public static float clamp(float value, float min, float max) {
+        return Math.max(min, Math.min(max, value));
+    }
+
+    /**
+     * @return the clamped {@param value} between the provided {@param min} and {@param max}.
+     */
+    public static int clamp(int value, int min, int max) {
+        return Math.max(min, Math.min(max, value));
+    }
+
+    /**
+     * @return the clamped {@param value} between 0 and 1.
+     */
+    public static float clamp01(float value) {
+        return Math.max(0f, Math.min(1f, value));
+    }
+
+    /**
+     * Scales the {@param value} to be proportionally between the {@param min} and
+     * {@param max} values.
+     *
+     * @param value must be between 0 and 1
+     */
+    public static float mapRange(@FloatRange(from=0.0,to=1.0) float value, float min, float max) {
+        return min + (value * (max - min));
+    }
+
+    /**
+     * Scales the {@param value} proportionally from {@param min} and {@param max} to 0 and 1.
+     *
+     * @param value must be between {@param min} and {@param max}
+     */
+    public static float unmapRange(float value, float min, float max) {
+        return (value - min) / (max - min);
+    }
+
     /** Scales a rect about its centroid */
     public static void scaleRectAboutCenter(RectF r, float scale) {
         if (scale != 1.0f) {
@@ -152,12 +197,25 @@
      */
     public static void cancelAnimationWithoutCallbacks(Animator animator) {
         if (animator != null) {
-            animator.removeAllListeners();
+            removeAnimationListenersRecursive(animator);
             animator.cancel();
         }
     }
 
     /**
+     * Recursively removes all the listeners of all children of this animator
+     */
+    public static void removeAnimationListenersRecursive(Animator animator) {
+        if (animator instanceof AnimatorSet) {
+            ArrayList<Animator> animators = ((AnimatorSet) animator).getChildAnimations();
+            for (int i = animators.size() - 1; i >= 0; i--) {
+                removeAnimationListenersRecursive(animators.get(i));
+            }
+        }
+        animator.removeAllListeners();
+    }
+
+    /**
      * Updates {@param transforms} to be the same size as {@param tasks}.
      */
     public static void matchTaskListSize(List<Task> tasks, List<TaskViewTransform> transforms) {
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 c51aa7c..824231a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -18,6 +18,8 @@
 
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -179,6 +181,7 @@
             }
 
             // Load the title, icon, and color
+            ActivityInfo info = loader.getAndUpdateActivityInfo(taskKey);
             String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
             String contentDescription = loader.getAndUpdateContentDescription(taskKey, res);
             String dismissDescription = dismissDescFormatter.format(dismissDescFormat,
@@ -188,11 +191,15 @@
                     : null;
             Bitmap thumbnail = loader.getAndUpdateThumbnail(taskKey, false);
             int activityColor = loader.getActivityPrimaryColor(t.taskDescription);
+            int backgroundColor = loader.getActivityBackgroundColor(t.taskDescription);
+            boolean isSystemApp = (info != null) &&
+                    ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
 
             // Add the task to the stack
             Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon,
                     thumbnail, title, contentDescription, dismissDescription, activityColor,
-                    !isStackTask, isLaunchTarget, t.bounds, t.taskDescription);
+                    backgroundColor, !isStackTask, isLaunchTarget, isSystemApp, t.bounds,
+                    t.taskDescription);
 
             allTasks.add(task);
             affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 26130ab..5e1af12 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -264,13 +264,16 @@
     private int mNumVisibleThumbnailsLoaded;
 
     int mDefaultTaskBarBackgroundColor;
+    int mDefaultTaskViewBackgroundColor;
     BitmapDrawable mDefaultIcon;
     Bitmap mDefaultThumbnail;
 
     public RecentsTaskLoader(Context context) {
         Resources res = context.getResources();
         mDefaultTaskBarBackgroundColor =
-                res.getColor(R.color.recents_task_bar_default_background_color);
+                context.getColor(R.color.recents_task_bar_default_background_color);
+        mDefaultTaskViewBackgroundColor =
+                context.getColor(R.color.recents_task_view_default_background_color);
         mMaxThumbnailCacheSize = res.getInteger(R.integer.config_recents_max_thumbnail_count);
         mMaxIconCacheSize = res.getInteger(R.integer.config_recents_max_icon_count);
         int iconCacheSize = RecentsDebugFlags.Static.DisableBackgroundCache ? 1 :
@@ -556,10 +559,20 @@
     }
 
     /**
+     * Returns the task's background color if possible.
+     */
+    int getActivityBackgroundColor(ActivityManager.TaskDescription td) {
+        if (td != null && td.getBackgroundColor() != 0) {
+            return td.getBackgroundColor();
+        }
+        return mDefaultTaskViewBackgroundColor;
+    }
+
+    /**
      * Returns the activity info for the given task key, retrieving one from the system if the
      * task key is expired.
      */
-    private ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) {
+    ActivityInfo getAndUpdateActivityInfo(Task.TaskKey taskKey) {
         SystemServicesProxy ssp = Recents.getSystemServices();
         ComponentName cn = taskKey.getComponent();
         ActivityInfo activityInfo = mActivityInfoCache.get(cn);
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 1c277d5..8ed6dd7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -23,6 +23,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.view.ViewDebug;
 
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -48,11 +49,17 @@
 
     /* The Task Key represents the unique primary key for the task */
     public static class TaskKey {
+        @ViewDebug.ExportedProperty(category="recents")
         public final int id;
+        @ViewDebug.ExportedProperty(category="recents")
         public int stackId;
+        @ViewDebug.ExportedProperty(category="recents")
         public final Intent baseIntent;
+        @ViewDebug.ExportedProperty(category="recents")
         public final int userId;
+        @ViewDebug.ExportedProperty(category="recents")
         public long firstActiveTime;
+        @ViewDebug.ExportedProperty(category="recents")
         public long lastActiveTime;
 
         private int mHashCode;
@@ -105,17 +112,21 @@
         }
     }
 
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="key_")
     public TaskKey key;
 
     /**
      * The group will be computed separately from the initialization of the task
      */
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="group_")
     public TaskGrouping group;
     /**
      * The affiliationTaskId is the task id of the parent task or itself if it is not affiliated
      * with any task.
      */
+    @ViewDebug.ExportedProperty(category="recents")
     public int affiliationTaskId;
+    @ViewDebug.ExportedProperty(category="recents")
     public int affiliationColor;
 
     /**
@@ -124,15 +135,23 @@
      */
     public Drawable icon;
     public Bitmap thumbnail;
+    @ViewDebug.ExportedProperty(category="recents")
     public String title;
+    @ViewDebug.ExportedProperty(category="recents")
     public String contentDescription;
+    @ViewDebug.ExportedProperty(category="recents")
     public String dismissDescription;
+    @ViewDebug.ExportedProperty(category="recents")
     public int colorPrimary;
+    @ViewDebug.ExportedProperty(category="recents")
+    public int colorBackground;
+    @ViewDebug.ExportedProperty(category="recents")
     public boolean useLightOnPrimaryColor;
 
     /**
      * The bounds of the task, used only if it is a freeform task.
      */
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect bounds;
 
     /**
@@ -143,8 +162,12 @@
     /**
      * The state isLaunchTarget will be set for the correct task upon launching Recents.
      */
+    @ViewDebug.ExportedProperty(category="recents")
     public boolean isLaunchTarget;
+    @ViewDebug.ExportedProperty(category="recents")
     public boolean isHistorical;
+    @ViewDebug.ExportedProperty(category="recents")
+    public boolean isSystemApp;
 
     private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>();
 
@@ -154,8 +177,8 @@
 
     public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon,
                 Bitmap thumbnail, String title, String contentDescription,
-                String dismissDescription, int colorPrimary, boolean isHistorical,
-                boolean isLaunchTarget, Rect bounds,
+                String dismissDescription, int colorPrimary, int colorBackground,
+                boolean isHistorical, boolean isLaunchTarget, boolean isSystemApp, Rect bounds,
                 ActivityManager.TaskDescription taskDescription) {
         boolean isInAffiliationGroup = (affiliationTaskId != key.id);
         boolean hasAffiliationGroupColor = isInAffiliationGroup && (affiliationColor != 0);
@@ -168,12 +191,14 @@
         this.contentDescription = contentDescription;
         this.dismissDescription = dismissDescription;
         this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary;
+        this.colorBackground = colorBackground;
         this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
                 Color.WHITE) > 3f;
         this.bounds = bounds;
         this.taskDescription = taskDescription;
         this.isLaunchTarget = isLaunchTarget;
         this.isHistorical = isHistorical;
+        this.isSystemApp = isSystemApp;
     }
 
     /** Copies the other task. */
@@ -188,10 +213,12 @@
         this.contentDescription = o.contentDescription;
         this.dismissDescription = o.dismissDescription;
         this.colorPrimary = o.colorPrimary;
+        this.colorBackground = o.colorBackground;
         this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
         this.bounds = o.bounds;
         this.isLaunchTarget = o.isLaunchTarget;
         this.isHistorical = o.isHistorical;
+        this.isSystemApp = o.isSystemApp;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
index 67a6a9f..d433b6c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyLruCache.java
@@ -96,6 +96,6 @@
 
     /** Trims the cache to a specific size */
     final void trimToSize(int cacheSize) {
-        mCache.resize(cacheSize);
+        mCache.trimToSize(cacheSize);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index fb86214..f3201d0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -287,13 +287,7 @@
         // wait on the system to send a signal that was never queued.
         RecentsConfiguration config = Recents.getConfiguration();
         RecentsActivityLaunchState launchState = config.getLaunchState();
-        launchState.launchedFromHome = false;
-        launchState.launchedFromSearchHome = false;
-        launchState.launchedFromAppWithThumbnail = false;
-        launchState.launchedToTaskId = -1;
-        launchState.launchedWithAltTab = false;
-        launchState.launchedHasConfigurationChanged = false;
-        launchState.launchedViaDragGesture = false;
+        launchState.reset();
     }
 
     @Override
@@ -324,13 +318,13 @@
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_UP: {
                 SystemServicesProxy ssp = Recents.getSystemServices();
-                PipManager.getInstance().showPipMenu();
+                PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_MENU);
                 ssp.focusPinnedStack();
                 return true;
             }
             case KeyEvent.KEYCODE_DPAD_DOWN: {
                 SystemServicesProxy ssp = Recents.getSystemServices();
-                PipManager.getInstance().showPipOverlay(false);
+                PipManager.getInstance().resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
                 ssp.focusHomeStack();
                 return true;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
index 8028327..48a1904 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/ViewFocusAnimator.java
@@ -47,7 +47,7 @@
         mTargetView.setOnFocusChangeListener(this);
 
         TypedValue out = new TypedValue();
-        res.getValue(R.raw.unselected_scale, out, true);
+        res.getValue(R.integer.unselected_scale, out, true);
         mUnselectedScale = out.getFloat();
         mSelectedScaleDelta = res.getFraction(R.fraction.lb_focus_zoom_factor_medium, 1, 1) -
                 mUnselectedScale;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
index 7b62f4e..f154331 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
@@ -65,7 +65,7 @@
     }
 
     public TaskStackHorizontalViewAdapter(List tasks) {
-        mTaskList = new ArrayList<>(tasks);
+        mTaskList = new ArrayList<Task>(tasks);
     }
 
     public void setNewStackTasks(List tasks) {
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 5842095..253d06a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -19,18 +19,28 @@
 import android.graphics.Outline;
 import android.graphics.Rect;
 import android.view.View;
+import android.view.ViewDebug;
 import android.view.ViewOutlineProvider;
 
+import com.android.systemui.recents.misc.Utilities;
+
 /* An outline provider that has a clip and outline that can be animated. */
 public class AnimateableViewBounds extends ViewOutlineProvider {
 
+    private static final float MIN_ALPHA = 0.1f;
+    private static final float MAX_ALPHA = 0.8f;
+
     View mSourceView;
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mClipRect = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mClipBounds = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mLastClipBounds = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
     int mCornerRadius;
+    @ViewDebug.ExportedProperty(category="recents")
     float mAlpha = 1f;
-    final float mMinAlpha = 0.25f;
 
     public AnimateableViewBounds(View source, int cornerRadius) {
         mSourceView = source;
@@ -47,7 +57,7 @@
 
     @Override
     public void getOutline(View view, Outline outline) {
-        outline.setAlpha(mMinAlpha + mAlpha / (1f - mMinAlpha));
+        outline.setAlpha(Utilities.mapRange(mAlpha, MIN_ALPHA, MAX_ALPHA));
         if (mCornerRadius > 0) {
             outline.setRoundRect(mClipRect.left, mClipRect.top,
                     mSourceView.getWidth() - mClipRect.right,
@@ -60,7 +70,9 @@
         }
     }
 
-    /** Sets the view outline alpha. */
+    /**
+     * Sets the view outline alpha.
+     */
     void setAlpha(float alpha) {
         if (Float.compare(alpha, mAlpha) != 0) {
             mAlpha = alpha;
@@ -69,6 +81,13 @@
         }
     }
 
+    /**
+     * @return the outline alpha.
+     */
+    public float getAlpha() {
+        return mAlpha;
+    }
+
     /** Sets the top clip. */
     public void setClipTop(int top) {
         mClipRect.top = top;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java
index 93878c5..48e1370 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimationProps.java
@@ -49,6 +49,8 @@
     public static final int ALPHA = 4;
     public static final int SCALE = 5;
     public static final int BOUNDS = 6;
+    public static final int DIM_ALPHA = 7;
+    public static final int FOCUS_STATE = 8;
 
     private SparseLongArray mPropStartDelay;
     private SparseLongArray mPropDuration;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 511aa3c..4359101 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -152,10 +152,11 @@
             transformOut.scale = 1f;
             transformOut.alpha = 1f;
             transformOut.translationZ = stackLayout.mMaxTranslationZ;
+            transformOut.dimAlpha = 0f;
+            transformOut.viewOutlineAlpha = TaskStackLayoutAlgorithm.OUTLINE_ALPHA_MAX_VALUE;
             transformOut.rect.set(ffRect);
             transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
             transformOut.visible = true;
-            transformOut.p = 1f;
             return transformOut;
         }
         return null;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 6c1ff9b..37b2859 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -49,6 +49,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+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.INVALID_STACK_ID;
@@ -99,8 +100,7 @@
 
         final ActivityOptions.OnAnimationStartedListener animStartedListener;
         final IAppTransitionAnimationSpecsFuture transitionFuture;
-        if (task.thumbnail != null && task.thumbnail.getWidth() > 0 &&
-                task.thumbnail.getHeight() > 0) {
+        if (taskView != null) {
             transitionFuture = getAppTransitionFuture(task, stackView, destinationStack);
             animStartedListener = new ActivityOptions.OnAnimationStartedListener() {
                 @Override
@@ -266,7 +266,11 @@
         // 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) {
+
+        // TODO: Sometimes targetStackId is not initialized after reboot, so we also have to
+        // check for INVALID_STACK_ID
+        if (targetStackId == FULLSCREEN_WORKSPACE_STACK_ID || targetStackId == DOCKED_STACK_ID
+                || targetStackId == INVALID_STACK_ID) {
             if (taskView == null) {
                 specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 5e113b9..2e45627 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.recents.views;
 
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -32,6 +34,7 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewDebug;
 import android.view.ViewOutlineProvider;
 import android.view.ViewPropertyAnimator;
 import android.view.WindowInsets;
@@ -79,8 +82,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-
 /**
  * This view is the the top level layout that contains TaskStacks (which are laid out according
  * to their SpaceNode bounds.
@@ -103,6 +104,8 @@
 
     private boolean mAwaitingFirstLayout = true;
     private boolean mLastTaskLaunchedWasFreeform;
+
+    @ViewDebug.ExportedProperty(category="recents")
     private Rect mSystemInsets = new Rect();
     private int mDividerSize;
 
@@ -110,6 +113,7 @@
     private Animator mBackgroundScrimAnimator;
 
     private RecentsTransitionHelper mTransitionHelper;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
     private RecentsViewTouchHandler mTouchHandler;
     private final FlingAnimationUtils mFlingAnimationUtils;
 
@@ -139,21 +143,24 @@
         final float cornerRadius = context.getResources().getDimensionPixelSize(
                 R.dimen.recents_task_view_rounded_corners_radius);
         LayoutInflater inflater = LayoutInflater.from(context);
-        mHistoryButton = (TextView) inflater.inflate(R.layout.recents_history_button, this, false);
-        mHistoryButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                EventBus.getDefault().send(new ToggleHistoryEvent());
-            }
-        });
-        addView(mHistoryButton);
-        mHistoryButton.setClipToOutline(true);
-        mHistoryButton.setOutlineProvider(new ViewOutlineProvider() {
-            @Override
-            public void getOutline(View view, Outline outline) {
-                outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), cornerRadius);
-            }
-        });
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            mHistoryButton = (TextView) inflater.inflate(R.layout.recents_history_button, this,
+                    false);
+            mHistoryButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    EventBus.getDefault().send(new ToggleHistoryEvent());
+                }
+            });
+            addView(mHistoryButton);
+            mHistoryButton.setClipToOutline(true);
+            mHistoryButton.setOutlineProvider(new ViewOutlineProvider() {
+                @Override
+                public void getOutline(View view, Outline outline) {
+                    outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), cornerRadius);
+                }
+            });
+        }
         mEmptyView = inflater.inflate(R.layout.recents_empty, this, false);
         addView(mEmptyView);
 
@@ -185,7 +192,8 @@
         // If we are already occluded by the app, then just set the default background scrim now.
         // Otherwise, defer until the enter animation completes to animate the scrim with the
         // tasks for the home animation.
-        if (launchState.launchedFromAppWithThumbnail || mStack.getTaskCount() == 0) {
+        if (launchState.launchedWhileDocking || launchState.launchedFromAppWithThumbnail
+                || mStack.getTaskCount() == 0) {
             mBackgroundScrim.setAlpha((int) (DEFAULT_SCRIM_ALPHA * 255));
         } else {
             mBackgroundScrim.setAlpha(0);
@@ -247,13 +255,18 @@
     }
 
     /** Launches the focused task from the first stack if possible */
-    public boolean launchFocusedTask() {
+    public boolean launchFocusedTask(int logEvent) {
         if (mTaskStackView != null) {
             Task task = mTaskStackView.getFocusedTask();
             if (task != null) {
                 TaskView taskView = mTaskStackView.getChildViewForTask(task);
                 EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null,
                         INVALID_STACK_ID, false));
+
+                if (logEvent != 0) {
+                    MetricsLogger.action(getContext(), logEvent,
+                            task.key.getComponent().toString());
+                }
                 return true;
             }
         }
@@ -321,7 +334,9 @@
         mTaskStackView.setVisibility(View.INVISIBLE);
         mEmptyView.setVisibility(View.VISIBLE);
         mEmptyView.bringToFront();
-        mHistoryButton.bringToFront();
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            mHistoryButton.bringToFront();
+        }
     }
 
     /**
@@ -337,7 +352,9 @@
         if (mSearchBar != null) {
             mSearchBar.bringToFront();
         }
-        mHistoryButton.bringToFront();
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            mHistoryButton.bringToFront();
+        }
     }
 
     @Override
@@ -387,21 +404,23 @@
                     MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
         }
 
-        // Measure the history view
-        if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
-            measureChild(mHistoryView, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
-        }
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            // Measure the history view
+            if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
+                measureChild(mHistoryView, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+            }
 
-        // Measure the history button within the constraints of the space above the stack
-        Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
-        measureChild(mHistoryButton,
-                MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.AT_MOST),
-                MeasureSpec.makeMeasureSpec(historyButtonRect.height(), MeasureSpec.AT_MOST));
-        if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
-            measureChild(mHistoryClearAllButton,
+            // Measure the history button within the constraints of the space above the stack
+            Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
+            measureChild(mHistoryButton,
                     MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.AT_MOST),
                     MeasureSpec.makeMeasureSpec(historyButtonRect.height(), MeasureSpec.AT_MOST));
+            if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
+                measureChild(mHistoryClearAllButton,
+                    MeasureSpec.makeMeasureSpec(historyButtonRect.width(), MeasureSpec.AT_MOST),
+                    MeasureSpec.makeMeasureSpec(historyButtonRect.height(), MeasureSpec.AT_MOST));
+            }
         }
 
         setMeasuredDimension(width, height);
@@ -433,36 +452,39 @@
             mEmptyView.layout(left, top, right, bottom);
         }
 
-        // Layout the history view
-        if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
-            mHistoryView.layout(left, top, right, bottom);
-        }
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            // Layout the history view
+            if (mHistoryView != null && mHistoryView.getVisibility() != GONE) {
+                mHistoryView.layout(left, top, right, bottom);
+            }
 
-        // Layout the history button such that its drawable is start-aligned with the stack,
-        // vertically centered in the available space above the stack
-        Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
-        int historyLeft = isLayoutRtl()
-                ? historyButtonRect.right + mHistoryButton.getPaddingStart()
-                        - mHistoryButton.getMeasuredWidth()
-                : historyButtonRect.left - mHistoryButton.getPaddingStart();
-        int historyTop = historyButtonRect.top +
-                (historyButtonRect.height() - mHistoryButton.getMeasuredHeight()) / 2;
-        mHistoryButton.layout(historyLeft, historyTop,
-                historyLeft + mHistoryButton.getMeasuredWidth(),
-                historyTop + mHistoryButton.getMeasuredHeight());
+            // Layout the history button such that its drawable is start-aligned with the stack,
+            // vertically centered in the available space above the stack
+            Rect historyButtonRect = mTaskStackView.mLayoutAlgorithm.mHistoryButtonRect;
+            int historyLeft = isLayoutRtl()
+                    ? historyButtonRect.right + mHistoryButton.getPaddingStart()
+                    - mHistoryButton.getMeasuredWidth()
+                    : historyButtonRect.left - mHistoryButton.getPaddingStart();
+            int historyTop = historyButtonRect.top +
+                    (historyButtonRect.height() - mHistoryButton.getMeasuredHeight()) / 2;
+            mHistoryButton.layout(historyLeft, historyTop,
+                    historyLeft + mHistoryButton.getMeasuredWidth(),
+                    historyTop + mHistoryButton.getMeasuredHeight());
 
-        // Layout the history clear all button such that it is end-aligned with the stack,
-        // vertically centered in the available space above the stack
-        if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
-            int clearAllLeft = isLayoutRtl()
-                    ? historyButtonRect.left - mHistoryClearAllButton.getPaddingStart()
-                    : historyButtonRect.right + mHistoryClearAllButton.getPaddingStart()
-                            - mHistoryClearAllButton.getMeasuredWidth();
-            int clearAllTop = historyButtonRect.top +
-                    (historyButtonRect.height() - mHistoryClearAllButton.getMeasuredHeight()) / 2;
-            mHistoryClearAllButton.layout(clearAllLeft, clearAllTop,
-                    clearAllLeft + mHistoryClearAllButton.getMeasuredWidth(),
-                    clearAllTop + mHistoryClearAllButton.getMeasuredHeight());
+            // Layout the history clear all button such that it is end-aligned with the stack,
+            // vertically centered in the available space above the stack
+            if (mHistoryClearAllButton != null && mHistoryClearAllButton.getVisibility() != GONE) {
+                int clearAllLeft = isLayoutRtl()
+                        ? historyButtonRect.left - mHistoryClearAllButton.getPaddingStart()
+                        : historyButtonRect.right + mHistoryClearAllButton.getPaddingStart()
+                        - mHistoryClearAllButton.getMeasuredWidth();
+                int clearAllTop = historyButtonRect.top +
+                        (historyButtonRect.height() - mHistoryClearAllButton.getMeasuredHeight()) /
+                                2;
+                mHistoryClearAllButton.layout(clearAllLeft, clearAllTop,
+                        clearAllLeft + mHistoryClearAllButton.getMeasuredWidth(),
+                        clearAllTop + mHistoryClearAllButton.getMeasuredHeight());
+            }
         }
 
         if (mAwaitingFirstLayout) {
@@ -530,9 +552,11 @@
     }
 
     public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
-        // Hide the history button
         int taskViewExitToHomeDuration = TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION;
-        hideHistoryButton(taskViewExitToHomeDuration, false /* translate */);
+        if (RecentsDebugFlags.Static.EnableHistory) {
+            // Hide the history button
+            hideHistoryButton(taskViewExitToHomeDuration, false /* translate */);
+        }
         animateBackgroundScrim(0f, taskViewExitToHomeDuration);
     }
 
@@ -645,7 +669,8 @@
 
     public final void onBusEvent(EnterRecentsWindowAnimationCompletedEvent event) {
         RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        if (!launchState.launchedFromAppWithThumbnail && mStack.getTaskCount() > 0) {
+        if (!launchState.launchedWhileDocking && !launchState.launchedFromAppWithThumbnail
+                && mStack.getTaskCount() > 0) {
             animateBackgroundScrim(DEFAULT_SCRIM_ALPHA,
                     TaskStackAnimationHelper.ENTER_FROM_HOME_TRANSLATION_DURATION);
         }
@@ -664,11 +689,17 @@
             // Reset the view state
             mAwaitingFirstLayout = true;
             mLastTaskLaunchedWasFreeform = false;
-            hideHistoryButton(0, false /* translate */);
+            if (RecentsDebugFlags.Static.EnableHistory) {
+                hideHistoryButton(0, false /* translate */);
+            }
         }
     }
 
     public final void onBusEvent(ToggleHistoryEvent event) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         if (mHistoryView != null && mHistoryView.isVisible()) {
             EventBus.getDefault().send(new HideHistoryEvent(true /* animate */));
         } else {
@@ -677,6 +708,10 @@
     }
 
     public final void onBusEvent(ShowHistoryEvent event) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         if (mHistoryView == null) {
             LayoutInflater inflater = LayoutInflater.from(getContext());
             mHistoryView = (RecentsHistoryView) inflater.inflate(R.layout.recents_history, this,
@@ -735,6 +770,10 @@
     }
 
     public final void onBusEvent(HideHistoryEvent event) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         // Animate the empty view in parallel with the history view (the task view animations are
         // handled in TaskStackView)
         Rect stackRect = mTaskStackView.mLayoutAlgorithm.mStackRect;
@@ -754,10 +793,18 @@
     }
 
     public final void onBusEvent(ShowHistoryButtonEvent event) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         showHistoryButton(150, event.translate);
     }
 
     public final void onBusEvent(HideHistoryButtonEvent event) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         hideHistoryButton(100, true /* translate */);
     }
 
@@ -765,6 +812,10 @@
      * Shows the history button.
      */
     private void showHistoryButton(final int duration, final boolean translate) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
         if (mHistoryButton.getVisibility() == View.INVISIBLE) {
             mHistoryButton.setVisibility(View.VISIBLE);
@@ -797,6 +848,10 @@
      * Hides the history button.
      */
     private void hideHistoryButton(int duration, boolean translate) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         final ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger();
         hideHistoryButton(duration, translate, postAnimationTrigger);
         postAnimationTrigger.flushLastDecrementRunnables();
@@ -807,6 +862,10 @@
      */
     private void hideHistoryButton(int duration, boolean translate,
             final ReferenceCountedTrigger postAnimationTrigger) {
+        if (!RecentsDebugFlags.Static.EnableHistory) {
+            return;
+        }
+
         if (mHistoryButton.getVisibility() == View.VISIBLE) {
             if (translate) {
                 mHistoryButton.animate()
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 346ce16..016d937 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -20,6 +20,7 @@
 import android.graphics.Point;
 import android.view.MotionEvent;
 import android.view.ViewConfiguration;
+import android.view.ViewDebug;
 
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsConfiguration;
@@ -61,12 +62,18 @@
 
     private RecentsView mRv;
 
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task")
     private Task mDragTask;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task_view_")
     private TaskView mTaskView;
 
+    @ViewDebug.ExportedProperty(category="recents")
     private Point mTaskViewOffset = new Point();
+    @ViewDebug.ExportedProperty(category="recents")
     private Point mDownPos = new Point();
+    @ViewDebug.ExportedProperty(category="recents")
     private boolean mDragRequested;
+    @ViewDebug.ExportedProperty(category="recents")
     private boolean mIsDragging;
     private float mDragSlop;
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 7eaa193..2cd0c19 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -23,6 +23,7 @@
 import android.graphics.Path;
 import android.graphics.RectF;
 import android.view.View;
+import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
 import com.android.systemui.Interpolators;
@@ -34,6 +35,7 @@
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -81,9 +83,18 @@
     private static final PathInterpolator EXIT_TO_HOME_ALPHA_INTERPOLATOR =
             new PathInterpolator(0.4f, 0, 1f, 1f);
 
+    private static final PathInterpolator FOCUS_NEXT_TASK_INTERPOLATOR =
+            new PathInterpolator(0.4f, 0, 0, 1f);
+    private static final PathInterpolator FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR =
+            new PathInterpolator(0, 0, 0, 1f);
+    private static final PathInterpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR =
+            new PathInterpolator(0.4f, 0, 0.2f, 1f);
+
     private TaskStackView mStackView;
 
     private TaskViewTransform mTmpTransform = new TaskViewTransform();
+    private ArrayList<TaskViewTransform> mTmpCurrentTaskTransforms = new ArrayList<>();
+    private ArrayList<TaskViewTransform> mTmpFinalTaskTransforms = new ArrayList<>();
 
     public TaskStackAnimationHelper(Context context, TaskStackView stackView) {
         mStackView = stackView;
@@ -418,4 +429,95 @@
             mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
         }
     }
+
+    /**
+     * Starts the animation to focus the next {@link TaskView} when paging through recents.
+     *
+     * @return whether or not this will trigger a scroll in the stack
+     */
+    public boolean startScrollToFocusedTaskAnimation(Task newFocusedTask,
+            boolean requestViewFocus) {
+        TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
+        TaskStackViewScroller stackScroller = mStackView.getScroller();
+        TaskStack stack = mStackView.getStack();
+
+        final float newScroll = stackLayout.getStackScrollForTask(newFocusedTask);
+        boolean willScrollToFront = newScroll > stackScroller.getStackScroll();
+        boolean willScroll = Float.compare(newScroll, stackScroller.getStackScroll()) != 0;
+
+        // Get the current set of task transforms
+        ArrayList<Task> stackTasks = stack.getStackTasks();
+        mStackView.getCurrentTaskTransforms(stackTasks, mTmpCurrentTaskTransforms);
+
+        // Pick up the newly visible views after the scroll
+        mStackView.bindVisibleTaskViews(newScroll);
+
+        // Update the internal state
+        stackLayout.setFocusState(TaskStackLayoutAlgorithm.STATE_FOCUSED);
+        stackScroller.setStackScroll(newScroll, null /* animation */);
+        mStackView.cancelDeferredTaskViewLayoutAnimation();
+
+        // Get the final set of task transforms
+        mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
+                mTmpFinalTaskTransforms);
+
+        // Focus the task view
+        TaskView newFocusedTaskView = mStackView.getChildViewForTask(newFocusedTask);
+        newFocusedTaskView.setFocusedState(true, requestViewFocus);
+
+        // Setup the end listener to return all the hidden views to the view pool after the
+        // focus animation
+        ReferenceCountedTrigger postAnimTrigger = new ReferenceCountedTrigger();
+        postAnimTrigger.addLastDecrementRunnable(new Runnable() {
+            @Override
+            public void run() {
+                mStackView.bindVisibleTaskViews(newScroll);
+            }
+        });
+
+        List<TaskView> taskViews = mStackView.getTaskViews();
+        int taskViewCount = taskViews.size();
+        int newFocusTaskViewIndex = taskViews.indexOf(newFocusedTaskView);
+        for (int i = 0; i < taskViewCount; i++) {
+            TaskView tv = taskViews.get(i);
+            Task task = tv.getTask();
+
+            if (mStackView.isIgnoredTask(task)) {
+                continue;
+            }
+
+            int taskIndex = stackTasks.indexOf(task);
+            TaskViewTransform fromTransform = mTmpCurrentTaskTransforms.get(taskIndex);
+            TaskViewTransform toTransform = mTmpFinalTaskTransforms.get(taskIndex);
+
+            // Update the task to the initial state (for the newly picked up tasks)
+            mStackView.updateTaskViewToTransform(tv, fromTransform, AnimationProps.IMMEDIATE);
+
+            int duration;
+            Interpolator interpolator;
+            if (willScrollToFront) {
+                duration = Math.max(100, 100 + ((i - 1) * 50));
+                interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
+            } else {
+                if (i < newFocusTaskViewIndex) {
+                    duration = 150 + ((newFocusTaskViewIndex - i - 1) * 50);
+                    interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
+                } else if (i > newFocusTaskViewIndex) {
+                    duration = Math.max(100, 150 - ((i - newFocusTaskViewIndex - 1) * 50));
+                    interpolator = FOCUS_IN_FRONT_NEXT_TASK_INTERPOLATOR;
+                } else {
+                    duration = 200;
+                    interpolator = FOCUS_NEXT_TASK_INTERPOLATOR;
+                }
+            }
+
+            AnimationProps anim = new AnimationProps()
+                    .setDuration(AnimationProps.BOUNDS, duration)
+                    .setInterpolator(AnimationProps.BOUNDS, interpolator)
+                    .setListener(postAnimTrigger.decrementOnAnimationEnd());
+            postAnimTrigger.increment();
+            mStackView.updateTaskViewToTransform(tv, toTransform, anim);
+        }
+        return willScroll;
+    }
 }
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 bd37c3b..88bebdb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.recents.views;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.Resources;
@@ -25,13 +27,13 @@
 import android.util.ArraySet;
 import android.util.FloatProperty;
 import android.util.Property;
+import android.view.ViewDebug;
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsActivityLaunchState;
 import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.misc.FreePathInterpolator;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
@@ -106,6 +108,32 @@
     // The scale factor to apply to the user movement in the stack to unfocus it
     private static final float UNFOCUS_MULTIPLIER = 0.8f;
 
+    // The distribution of view bounds alpha
+    // XXX: This is a hack because you can currently set the max alpha to be > 1f
+    public static final float OUTLINE_ALPHA_MIN_VALUE = 0f;
+    public static final float OUTLINE_ALPHA_MAX_VALUE = 2f;
+
+    // The distribution of dim to apply to tasks in the stack
+    private static final float DIM_MAX_VALUE = 0.35f;
+    private static final Path UNFOCUSED_DIM_PATH = new Path();
+    private static final Path FOCUSED_DIM_PATH = new Path();
+    static {
+        // The unfocused dim interpolator peaks to 1 at 0.5 (the focused task), then slowly drops
+        // back to 0.5 at the front of the stack
+        UNFOCUSED_DIM_PATH.moveTo(0f, 0f);
+        UNFOCUSED_DIM_PATH.cubicTo(0f, 0.1f, 0.4f, 0.8f, 0.5f, 1f);
+        UNFOCUSED_DIM_PATH.cubicTo(0.6f, 1f, 0.9f, 0.6f, 1f, 0.5f);
+        // The focused dim interpolator peaks to 1 at 0.5 (the focused task), then drops back to 0
+        // at the front of the stack
+        FOCUSED_DIM_PATH.moveTo(0f, 0f);
+        FOCUSED_DIM_PATH.cubicTo(0.1f, 0f, 0.4f, 1f, 0.5f, 1f);
+        FOCUSED_DIM_PATH.cubicTo(0.6f, 1f, 0.9f, 0f, 1f, 0f);
+    }
+    private static final FreePathInterpolator UNFOCUSED_DIM_INTERPOLATOR =
+            new FreePathInterpolator(UNFOCUSED_DIM_PATH);
+    private static final FreePathInterpolator FOCUSED_DIM_INTERPOLATOR =
+            new FreePathInterpolator(FOCUSED_DIM_PATH);
+
     // The various focus states
     public static final float STATE_FOCUSED = 1f;
     public static final float STATE_UNFOCUSED = 0f;
@@ -216,15 +244,20 @@
     private TaskStackLayoutAlgorithmCallbacks mCb;
 
     // The task bounds (untransformed) for layout.  This rect is anchored at mTaskRoot.
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect mTaskRect = new Rect();
     // The freeform workspace bounds, inset from the top by the search bar, and is a fixed height
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect mFreeformRect = new Rect();
     // The stack bounds, inset from the top by the search bar, and runs to
     // the bottom of the screen
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect mStackRect = new Rect();
     // This is the current system insets
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect mSystemInsets = new Rect();
     // This is the bounds of the history button above the stack rect
+    @ViewDebug.ExportedProperty(category="recents")
     public Rect mHistoryButtonRect = new Rect();
 
     // The visible ranges when the stack is focused and unfocused
@@ -232,14 +265,19 @@
     private Range mFocusedRange;
 
     // The offset from the top when scrolled to the top of the stack
-    private int mFocusedPeekHeight;
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mFocusedTopPeekHeight;
+    @ViewDebug.ExportedProperty(category="recents")
+    private int mFocusedBottomTaskPeekHeight;
 
     // The offset from the top of the stack to the top of the bounds when the stack is scrolled to
     // the end
+    @ViewDebug.ExportedProperty(category="recents")
     private int mStackTopOffset;
 
     // The offset from the bottom of the stack to the bottom of the bounds when the stack is
     // scrolled to the front
+    @ViewDebug.ExportedProperty(category="recents")
     private int mStackBottomOffset;
 
     // The paths defining the motion of the tasks when the stack is focused and unfocused
@@ -250,27 +288,36 @@
 
     // The state of the stack focus (0..1), which controls the transition of the stack from the
     // focused to non-focused state
+    @ViewDebug.ExportedProperty(category="recents")
     private float mFocusState;
 
     // The animator used to reset the focused state
     private ObjectAnimator mFocusStateAnimator;
 
     // The smallest scroll progress, at this value, the back most task will be visible
+    @ViewDebug.ExportedProperty(category="recents")
     float mMinScrollP;
     // The largest scroll progress, at this value, the front most task will be visible above the
     // navigation bar
+    @ViewDebug.ExportedProperty(category="recents")
     float mMaxScrollP;
     // The initial progress that the scroller is set when you first enter recents
+    @ViewDebug.ExportedProperty(category="recents")
     float mInitialScrollP;
     // The task progress for the front-most task in the stack
+    @ViewDebug.ExportedProperty(category="recents")
     float mFrontMostTaskP;
 
     // The last computed task counts
+    @ViewDebug.ExportedProperty(category="recents")
     int mNumStackTasks;
+    @ViewDebug.ExportedProperty(category="recents")
     int mNumFreeformTasks;
 
     // The min/max z translations
+    @ViewDebug.ExportedProperty(category="recents")
     int mMinTranslationZ;
+    @ViewDebug.ExportedProperty(category="recents")
     int mMaxTranslationZ;
 
     // Optimization, allows for quick lookup of task -> index
@@ -293,7 +340,10 @@
         mUnfocusedRange = new Range(res.getFloat(R.integer.recents_layout_unfocused_range_min),
                 res.getFloat(R.integer.recents_layout_unfocused_range_max));
         mFocusState = getDefaultFocusState();
-        mFocusedPeekHeight = res.getDimensionPixelSize(R.dimen.recents_layout_focused_peek_size);
+        mFocusedTopPeekHeight =
+                res.getDimensionPixelSize(R.dimen.recents_layout_focused_top_peek_size);
+        mFocusedBottomTaskPeekHeight =
+                res.getDimensionPixelSize(R.dimen.recents_layout_focused_bottom_task_peek_size);
 
         mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
         mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
@@ -347,19 +397,19 @@
         // The freeform height is the visible height (not including system insets) - padding above
         // freeform and below stack - gap between the freeform and stack
         mState = state;
-        mStackTopOffset = mFocusedPeekHeight + heightPadding;
+        mStackTopOffset = mFocusedTopPeekHeight + heightPadding;
         mStackBottomOffset = mSystemInsets.bottom + heightPadding;
         state.computeRects(mFreeformRect, mStackRect, taskStackBounds, widthPadding, heightPadding,
                 mStackBottomOffset);
         // The history button will take the full un-padded header space above the stack
         mHistoryButtonRect.set(mStackRect.left, mStackRect.top - heightPadding,
-                mStackRect.right, mStackRect.top + mFocusedPeekHeight);
+                mStackRect.right, mStackRect.top + mFocusedTopPeekHeight);
 
         // Anchor the task rect to the top-center of the non-freeform stack rect
         float aspect = (float) (taskStackBounds.width() - mSystemInsets.left - mSystemInsets.right)
                 / (taskStackBounds.height() - mSystemInsets.bottom);
         int width = mStackRect.width();
-        int minHeight = mStackRect.height() - mFocusedPeekHeight - mStackBottomOffset;
+        int minHeight = mStackRect.height() - mFocusedTopPeekHeight - mStackBottomOffset;
         int height = (int) Math.min(width / aspect, minHeight);
         mTaskRect.set(mStackRect.left, mStackRect.top,
                 mStackRect.left + width, mStackRect.top + height);
@@ -434,8 +484,8 @@
                         mStackRect.height();
                 float normX = mUnfocusedCurveInterpolator.getX(bottomOffsetPct);
                 mMinScrollP = 0;
-                mMaxScrollP = Math.max(mMinScrollP,
-                        (mNumStackTasks - 1) - Math.max(0, mUnfocusedRange.getAbsoluteX(normX)));
+                mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
+                        Math.max(0, mUnfocusedRange.getAbsoluteX(normX)));
             }
         }
 
@@ -451,16 +501,16 @@
                 mInitialScrollP = mMinScrollP;
             } else if (getDefaultFocusState() > 0f) {
                 if (launchState.launchedFromHome) {
-                    mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, launchTaskIndex));
+                    mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
                 } else {
-                    mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP,
-                            launchTaskIndex - 1));
+                    mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP,
+                            mMaxScrollP);
                 }
             } else {
-                float offsetPct = (float) (mTaskRect.height() / 2) / mStackRect.height();
+                float offsetPct = (float) (mTaskRect.height() / 3) / mStackRect.height();
                 float normX = mUnfocusedCurveInterpolator.getX(offsetPct);
-                mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP,
-                        launchTaskIndex - mUnfocusedRange.getAbsoluteX(normX)));
+                mInitialScrollP = Utilities.clamp(launchTaskIndex -
+                        mUnfocusedRange.getAbsoluteX(normX), mMinScrollP, mMaxScrollP);
             }
         }
     }
@@ -495,12 +545,7 @@
      * Returns the default focus state.
      */
     public float getDefaultFocusState() {
-        RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
-        RecentsDebugFlags debugFlags = Recents.getDebugFlags();
-        if (launchState.launchedWithAltTab || debugFlags.isInitialStatePaging()) {
-            return STATE_FOCUSED;
-        }
-        return STATE_UNFOCUSED;
+        return STATE_FOCUSED;
     }
 
     /**
@@ -567,7 +612,7 @@
 
             boolean isFrontMostTaskInGroup = task.group == null || task.group.isFrontMostTask(task);
             if (isFrontMostTaskInGroup) {
-                getStackTransform(taskProgress, mInitialScrollP, tmpTransform, null,
+                getStackTransform(taskProgress, mInitialScrollP, mFocusState, tmpTransform, null,
                         false /* ignoreSingleTaskCase */, false /* forceUpdate */);
                 float screenY = tmpTransform.rect.top;
                 boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
@@ -601,11 +646,11 @@
      */
     public TaskViewTransform getStackTransform(Task task, float stackScroll,
             TaskViewTransform transformOut, TaskViewTransform frontTransform) {
-        return getStackTransform(task, stackScroll, transformOut, frontTransform,
+        return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
                 false /* forceUpdate */);
     }
 
-    public TaskViewTransform getStackTransform(Task task, float stackScroll,
+    public TaskViewTransform getStackTransform(Task task, float stackScroll, float focusState,
         TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate) {
         if (mFreeformLayoutAlgorithm.isTransformAvailable(task, this)) {
             mFreeformLayoutAlgorithm.getTransform(task, transformOut, this);
@@ -616,7 +661,7 @@
                 transformOut.reset();
                 return transformOut;
             }
-            getStackTransform(mTaskIndexMap.get(task.key), stackScroll, transformOut,
+            getStackTransform(mTaskIndexMap.get(task.key), stackScroll, focusState, transformOut,
                     frontTransform, false /* ignoreSingleTaskCase */, forceUpdate);
             return transformOut;
         }
@@ -642,27 +687,21 @@
      *                             internally to ensure that we can calculate the transform for any
      *                             position in the stack.
      */
-    public void getStackTransform(float taskProgress, float stackScroll,
+    public void getStackTransform(float taskProgress, float stackScroll, float focusState,
             TaskViewTransform transformOut, TaskViewTransform frontTransform,
             boolean ignoreSingleTaskCase, boolean forceUpdate) {
         SystemServicesProxy ssp = Recents.getSystemServices();
 
         // Compute the focused and unfocused offset
+        float boundedStackScroll = Utilities.clamp(stackScroll, mMinScrollP, mMaxScrollP);
+        mUnfocusedRange.offset(boundedStackScroll);
+        mFocusedRange.offset(boundedStackScroll);
+        float boundedScrollUnfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress);
+        float boundedScrollFocusedRangeX = mFocusedRange.getNormalizedX(taskProgress);
         mUnfocusedRange.offset(stackScroll);
-        float p = mUnfocusedRange.getNormalizedX(taskProgress);
-        float yp = mUnfocusedCurveInterpolator.getInterpolation(p);
-        float unfocusedP = p;
-        int unFocusedY = (int) (Math.max(0f, (1f - yp)) * mStackRect.height());
+        mFocusedRange.offset(stackScroll);
         boolean unfocusedVisible = mUnfocusedRange.isInRange(taskProgress);
-        int focusedY = 0;
-        boolean focusedVisible = true;
-        if (mFocusState > 0f) {
-            mFocusedRange.offset(stackScroll);
-            p = mFocusedRange.getNormalizedX(taskProgress);
-            yp = mFocusedCurveInterpolator.getInterpolation(p);
-            focusedY = (int) (Math.max(0f, (1f - yp)) * mStackRect.height());
-            focusedVisible = mFocusedRange.isInRange(taskProgress);
-        }
+        boolean focusedVisible = mFocusedRange.isInRange(taskProgress);
 
         // Skip if the task is not visible
         if (!forceUpdate && !unfocusedVisible && !focusedVisible) {
@@ -670,43 +709,56 @@
             return;
         }
 
+        float unfocusedRangeX = mUnfocusedRange.getNormalizedX(taskProgress);
+        float focusedRangeX = mFocusedRange.getNormalizedX(taskProgress);
+
         int x = (mStackRect.width() - mTaskRect.width()) / 2;
         int y;
         float z;
-        float relP;
+        float dimAlpha;
+        float viewOutlineAlpha;
         if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1 && !ignoreSingleTaskCase) {
             // When there is exactly one task, then decouple the task from the stack and just move
             // in screen space
-            p = (mMinScrollP - stackScroll) / mNumStackTasks;
+            float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
             int centerYOffset = (mStackRect.top - mTaskRect.top) +
                     (mStackRect.height() - mTaskRect.height()) / 2;
-            y = centerYOffset + getYForDeltaP(p, 0);
+            y = centerYOffset + getYForDeltaP(tmpP, 0);
             z = mMaxTranslationZ;
-            relP = 1f;
+            dimAlpha = 0f;
+            viewOutlineAlpha = (OUTLINE_ALPHA_MIN_VALUE + OUTLINE_ALPHA_MAX_VALUE) / 2f;
 
         } else {
             // Otherwise, update the task to the stack layout
-            y = unFocusedY + (int) (mFocusState * (focusedY - unFocusedY));
-            y += (mStackRect.top - mTaskRect.top);
-            z = Math.max(mMinTranslationZ, Math.min(mMaxTranslationZ,
-                    mMinTranslationZ + (p * (mMaxTranslationZ - mMinTranslationZ))));
-            if (mNumStackTasks == 1) {
-                relP = 1f;
-            } else {
-                relP = Math.min(mMaxScrollP, unfocusedP);
-            }
+            int unfocusedY = (int) ((1f - mUnfocusedCurveInterpolator.getInterpolation(
+                    unfocusedRangeX)) * mStackRect.height());
+            int focusedY = (int) ((1f - mFocusedCurveInterpolator.getInterpolation(
+                    focusedRangeX)) * mStackRect.height());
+            float unfocusedDim = 1f - UNFOCUSED_DIM_INTERPOLATOR.getInterpolation(
+                    boundedScrollUnfocusedRangeX);
+            float focusedDim = 1f - FOCUSED_DIM_INTERPOLATOR.getInterpolation(
+                    boundedScrollFocusedRangeX);
+
+            y = (mStackRect.top - mTaskRect.top) +
+                    (int) Utilities.mapRange(focusState, unfocusedY, focusedY);
+            z = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedRangeX),
+                    mMinTranslationZ, mMaxTranslationZ);
+            dimAlpha = DIM_MAX_VALUE * Utilities.mapRange(focusState, unfocusedDim, focusedDim);
+            viewOutlineAlpha = Utilities.mapRange(Utilities.clamp01(boundedScrollUnfocusedRangeX),
+                    OUTLINE_ALPHA_MIN_VALUE, OUTLINE_ALPHA_MAX_VALUE);
         }
 
         // Fill out the transform
         transformOut.scale = 1f;
         transformOut.alpha = 1f;
         transformOut.translationZ = z;
+        transformOut.dimAlpha = dimAlpha;
+        transformOut.viewOutlineAlpha = viewOutlineAlpha;
         transformOut.rect.set(mTaskRect);
         transformOut.rect.offset(x, y);
         Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
         transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
                 (frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
-        transformOut.p = relP;
     }
 
     /**
@@ -750,18 +802,17 @@
      * Creates a new path for the focused curve.
      */
     private Path constructFocusedCurve() {
-        int taskBarHeight = mContext.getResources().getDimensionPixelSize(
-                R.dimen.recents_task_bar_height);
-
         // Initialize the focused curve. This curve is a piecewise curve composed of several
-        // quadradic beziers that goes from (0,1) through (0.5, peek height offset),
-        // (0.667, next task offset), (0.833, bottom task offset), and (1,0).
-        float peekHeightPct = (float) mFocusedPeekHeight / mStackRect.height();
+        // linear pieces that goes from (0,1) through (0.5, peek height offset),
+        // (0.5, bottom task offsets), and (1,0).
+        float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
+        float bottomPeekHeightPct = Math.max(
+                mSystemInsets.bottom + mFocusedRange.relativeMax * mFocusedBottomTaskPeekHeight,
+                mStackBottomOffset + mFocusedBottomTaskPeekHeight) / mStackRect.height();
         Path p = new Path();
         p.moveTo(0f, 1f);
-        p.lineTo(0.5f, 1f - peekHeightPct);
-        p.lineTo(0.66666667f, (float) (taskBarHeight * 3) / mStackRect.height());
-        p.lineTo(0.83333333f, (float) (taskBarHeight / 2) / mStackRect.height());
+        p.lineTo(0.5f, 1f - topPeekHeightPct);
+        p.lineTo(0.5f + (0.5f / mFocusedRange.relativeMax), bottomPeekHeightPct);
         p.lineTo(1f, 0f);
         return p;
     }
@@ -778,7 +829,7 @@
         // there is a tangent at (0.5, peek height offset).
         float cpoint1X = 0.4f;
         float cpoint1Y = 1f;
-        float peekHeightPct = (float) mFocusedPeekHeight / mStackRect.height();
+        float peekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
         float slope = ((1f - peekHeightPct) - cpoint1Y) / (0.5f - cpoint1X);
         float b = 1f - slope * cpoint1X;
         float cpoint2X = 0.75f;
@@ -799,14 +850,14 @@
             return;
         }
 
-        float min = mUnfocusedRange.relativeMin +
-                mFocusState * (mFocusedRange.relativeMin - mUnfocusedRange.relativeMin);
-        float max = mUnfocusedRange.relativeMax +
-                mFocusState * (mFocusedRange.relativeMax - mUnfocusedRange.relativeMax);
-        getStackTransform(min, 0f, mBackOfStackTransform, null, true /* ignoreSingleTaskCase */,
-                true /* forceUpdate */);
-        getStackTransform(max, 0f, mFrontOfStackTransform, null, true /* ignoreSingleTaskCase */,
-                true /* forceUpdate */);
+        float min = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMin,
+                mFocusedRange.relativeMin);
+        float max = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMax,
+                mFocusedRange.relativeMax);
+        getStackTransform(min, 0f, mFocusState, mBackOfStackTransform, null,
+                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
+        getStackTransform(max, 0f, mFocusState, mFrontOfStackTransform, null,
+                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
         mBackOfStackTransform.visible = true;
         mFrontOfStackTransform.visible = true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index bb74de4..1707c4f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -38,11 +38,14 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -113,9 +116,13 @@
 
     private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
 
+    LayoutInflater mInflater;
     TaskStack mStack;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="scroller_")
     TaskStackViewScroller mStackScroller;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="touch_")
     TaskStackViewTouchHandler mTouchHandler;
     TaskStackAnimationHelper mAnimationHelper;
     GradientDrawable mFreeformWorkspaceBackground;
@@ -127,31 +134,41 @@
     ArraySet<Task.TaskKey> mIgnoreTasks = new ArraySet<>();
     AnimationProps mDeferredTaskViewLayoutAnimation = null;
 
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="doze_")
     DozeTrigger mUIDozeTrigger;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="focused_task_")
     Task mFocusedTask;
 
     int mTaskCornerRadiusPx;
     private int mDividerSize;
     private int mStartTimerIndicatorDuration;
 
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mTaskViewsClipDirty = true;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mAwaitingFirstLayout = true;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mInMeasureLayout = false;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mEnterAnimationComplete = false;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mTouchExplorationEnabled;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mScreenPinningEnabled;
 
     // The stable stack bounds are the full bounds that we were measured with from RecentsView
-    Rect mStableStackBounds = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
+    private Rect mStableStackBounds = new Rect();
     // The current stack bounds are dynamic and may change as the user drags and drops
-    Rect mStackBounds = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
+    private Rect mStackBounds = new Rect();
 
-    int[] mTmpVisibleRange = new int[2];
-    Rect mTmpRect = new Rect();
-    ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
-    List<TaskView> mTmpTaskViews = new ArrayList<>();
-    TaskViewTransform mTmpTransform = new TaskViewTransform();
-    LayoutInflater mInflater;
+    @ViewDebug.ExportedProperty(category="recents")
+    private int[] mTmpVisibleRange = new int[2];
+    private Rect mTmpRect = new Rect();
+    private ArrayMap<Task.TaskKey, TaskView> mTmpTaskViewMap = new ArrayMap<>();
+    private List<TaskView> mTmpTaskViews = new ArrayList<>();
+    private TaskViewTransform mTmpTransform = new TaskViewTransform();
 
     // A convenience update listener to request updating clipping of tasks
     private ValueAnimator.AnimatorUpdateListener mRequestUpdateClippingListener =
@@ -396,6 +413,7 @@
         int frontMostVisibleIndex = -1;
         int backMostVisibleIndex = -1;
         boolean useTargetStackScroll = Float.compare(curStackScroll, targetStackScroll) != 0;
+        boolean targetScrollIsInFront = targetStackScroll > curStackScroll;
 
         // We can reuse the task transforms where possible to reduce object allocation
         Utilities.matchTaskListSize(tasks, taskTransforms);
@@ -439,7 +457,7 @@
                     frontMostVisibleIndex = i;
                 }
                 backMostVisibleIndex = i;
-            } else {
+            } else if (!targetScrollIsInFront) {
                 if (backMostVisibleIndex != -1) {
                     // We've reached the end of the visible range, so going down the rest of the
                     // stack, we can just reset the transforms accordingly
@@ -531,7 +549,7 @@
             }
 
             // Skip the invisible non-freeform stack tasks
-            if (i > visibleStackRange[0] && !task.isFreeformTask()) {
+            if (!task.isFreeformTask() && !transform.visible) {
                 continue;
             }
 
@@ -542,7 +560,7 @@
                     tv.updateViewPropertiesToTaskTransform(transform, AnimationProps.IMMEDIATE,
                             mRequestUpdateClippingListener);
                 } else {
-                    if (Float.compare(transform.p, 0f) <= 0) {
+                    if (transform.rect.top <= mLayoutAlgorithm.mStackRect.top) {
                         tv.updateViewPropertiesToTaskTransform(
                                 mLayoutAlgorithm.getBackOfStackTransform(),
                                 AnimationProps.IMMEDIATE, mRequestUpdateClippingListener);
@@ -647,6 +665,7 @@
     public void getCurrentTaskTransforms(ArrayList<Task> tasks,
             ArrayList<TaskViewTransform> transformsOut) {
         Utilities.matchTaskListSize(tasks, transformsOut);
+        float focusState = mLayoutAlgorithm.getFocusState();
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task task = tasks.get(i);
             TaskViewTransform transform = transformsOut.get(i);
@@ -655,7 +674,7 @@
                 transform.fillIn(tv);
             } else {
                 mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
-                        transform, null, true /* forceUpdate */);
+                        focusState, transform, null, true /* forceUpdate */);
             }
             transform.visible = true;
         }
@@ -663,20 +682,28 @@
 
     /**
      * Returns the task transforms for all the tasks in the stack if the stack was at the given
-     * {@param stackScroll}.
+     * {@param stackScroll} and {@param focusState}.
      */
-    public void getLayoutTaskTransforms(float stackScroll, ArrayList<Task> tasks,
+    public void getLayoutTaskTransforms(float stackScroll, float focusState, ArrayList<Task> tasks,
             ArrayList<TaskViewTransform> transformsOut) {
         Utilities.matchTaskListSize(tasks, transformsOut);
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task task = tasks.get(i);
             TaskViewTransform transform = transformsOut.get(i);
-            mLayoutAlgorithm.getStackTransform(task, stackScroll, transform, null);
+            mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
+                    true /* forceUpdate */);
             transform.visible = true;
         }
     }
 
     /**
+     * Cancels the next deferred task view layout.
+     */
+    void cancelDeferredTaskViewLayoutAnimation() {
+        mDeferredTaskViewLayoutAnimation = null;
+    }
+
+    /**
      * Cancels all {@link TaskView} animations.
      *
      * @see #cancelAllTaskViewAnimations(ArraySet<Task.TaskKey>)
@@ -716,7 +743,7 @@
             TaskView frontTv = null;
             int clipBottom = 0;
 
-            if (mIgnoreTasks.contains(tv.getTask().key)) {
+            if (isIgnoredTask(tv.getTask())) {
                 // For each of the ignore tasks, update the translationZ of its TaskView to be
                 // between the translationZ of the tasks immediately underneath it
                 if (prevVisibleTv != null) {
@@ -804,15 +831,15 @@
     }
 
     /**
-     * Sets the focused task to the provided (bounded taskIndex).
+     * Sets the focused task to the provided (bounded focusTaskIndex).
      *
      * @return whether or not the stack will scroll as a part of this focus change
      */
-    private boolean setFocusedTask(int taskIndex, boolean scrollToTask,
-            final boolean requestViewFocus, final int timerIndicatorDuration) {
+    private boolean setFocusedTask(int focusTaskIndex, boolean scrollToTask,
+            boolean requestViewFocus, int timerIndicatorDuration) {
         // Find the next task to focus
         int newFocusedTaskIndex = mStack.getTaskCount() > 0 ?
-                Math.max(0, Math.min(mStack.getTaskCount() - 1, taskIndex)) : -1;
+                Utilities.clamp(focusTaskIndex, 0, mStack.getTaskCount() - 1) : -1;
         final Task newFocusedTask = (newFocusedTaskIndex != -1) ?
                 mStack.getStackTasks().get(newFocusedTaskIndex) : null;
 
@@ -830,7 +857,6 @@
         }
 
         boolean willScroll = false;
-
         mFocusedTask = newFocusedTask;
 
         if (newFocusedTask != null) {
@@ -845,33 +871,20 @@
                 }
             }
 
-            Runnable focusTaskRunnable = new Runnable() {
-                @Override
-                public void run() {
-                    final TaskView tv = getChildViewForTask(newFocusedTask);
-                    if (tv != null) {
-                        tv.setFocusedState(true, requestViewFocus);
-                    }
-                }
-            };
-
             if (scrollToTask) {
                 // Cancel any running enter animations at this point when we scroll or change focus
                 if (!mEnterAnimationComplete) {
                     cancelAllTaskViewAnimations();
                 }
 
-                // TODO: Center the newly focused task view, only if not freeform
-                float newScroll = mLayoutAlgorithm.getStackScrollForTask(newFocusedTask);
-                if (Float.compare(newScroll, mStackScroller.getStackScroll()) != 0) {
-                    mStackScroller.animateScroll(newScroll, focusTaskRunnable);
-                    willScroll = true;
-                } else {
-                    focusTaskRunnable.run();
-                }
-                mLayoutAlgorithm.animateFocusState(TaskStackLayoutAlgorithm.STATE_FOCUSED);
+                willScroll = mAnimationHelper.startScrollToFocusedTaskAnimation(newFocusedTask,
+                        requestViewFocus);
             } else {
-                focusTaskRunnable.run();
+                // Focus the task view
+                TaskView newFocusedTaskView = getChildViewForTask(newFocusedTask);
+                if (newFocusedTaskView != null) {
+                    newFocusedTaskView.setFocusedState(true, requestViewFocus);
+                }
             }
         }
         return willScroll;
@@ -951,10 +964,26 @@
                 newIndex = (newIndex + (forward ? -1 : 1) + taskCount) % taskCount;
             }
         } else {
-            // We don't have a focused task, so focus the first visible task view
-            TaskView tv = getFrontMostTaskView(stackTasksOnly);
-            if (tv != null) {
-                newIndex = mStack.indexOfStackTask(tv.getTask());
+            // We don't have a focused task
+            float stackScroll = mStackScroller.getStackScroll();
+            ArrayList<Task> tasks = mStack.getStackTasks();
+            int taskCount = tasks.size();
+            if (forward) {
+                // Walk backwards and focus the next task smaller than the current stack scroll
+                for (newIndex = taskCount - 1; newIndex >= 0; newIndex--) {
+                    float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
+                    if (Float.compare(taskP, stackScroll) <= 0) {
+                        break;
+                    }
+                }
+            } else {
+                // Walk forwards and focus the next task larger than the current stack scroll
+                for (newIndex = 0; newIndex < taskCount; newIndex++) {
+                    float taskP = mLayoutAlgorithm.getStackScrollForTask(tasks.get(newIndex));
+                    if (Float.compare(taskP, stackScroll) >= 0) {
+                        break;
+                    }
+                }
             }
         }
         if (newIndex != -1) {
@@ -1276,7 +1305,7 @@
             Task task = tasks.get(i);
 
             // Ignore deleting tasks
-            if (mIgnoreTasks.contains(task.key)) {
+            if (isIgnoredTask(task)) {
                 if (i == tasks.size() - 1) {
                     isFrontMostTask.value = true;
                 }
@@ -1390,7 +1419,7 @@
     }
 
     @Override
-    public void prepareViewToEnterPool(TaskView tv) {
+    public void onReturnViewToPool(TaskView tv) {
         final Task task = tv.getTask();
 
         // Report that this tasks's data is no longer being used
@@ -1411,7 +1440,7 @@
     }
 
     @Override
-    public void prepareViewToLeavePool(TaskView tv, Task task, boolean isNewView) {
+    public void onPickUpViewFromPool(TaskView tv, Task task, boolean isNewView) {
         // Find the index where this task should be placed in the stack
         int taskIndex = mStack.indexOfStackTask(task);
         int insertIndex = findTaskViewInsertIndex(task, taskIndex);
@@ -1498,7 +1527,7 @@
     /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
 
     @Override
-    public void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
+    public void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
         mUIDozeTrigger.poke();
         if (animation != null) {
             relayoutTaskViewsOnNextFrame(animation);
@@ -1601,6 +1630,9 @@
     public final void onBusEvent(TaskViewDismissedEvent event) {
         removeTaskViewFromStack(event.taskView, event.task);
         EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
+
+        MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
+                event.task.key.getComponent().toString());
     }
 
     public final void onBusEvent(FocusNextTaskViewEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index c641d75..333df9d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -23,6 +23,7 @@
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Property;
+import android.view.ViewDebug;
 import android.widget.OverScroller;
 
 import com.android.systemui.Interpolators;
@@ -38,7 +39,7 @@
     private static final boolean DEBUG = false;
 
     public interface TaskStackViewScrollerCallbacks {
-        void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation);
+        void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation);
     }
 
     /**
@@ -63,6 +64,7 @@
     TaskStackLayoutAlgorithm mLayoutAlgorithm;
     TaskStackViewScrollerCallbacks mCb;
 
+    @ViewDebug.ExportedProperty(category="recents")
     float mStackScrollP;
     float mFlingDownScrollP;
     int mFlingDownY;
@@ -104,7 +106,7 @@
         float prevStackScroll = mStackScrollP;
         mStackScrollP = s;
         if (mCb != null) {
-            mCb.onScrollChanged(prevStackScroll, mStackScrollP, animation);
+            mCb.onStackScrollChanged(prevStackScroll, mStackScrollP, animation);
         }
     }
 
@@ -150,8 +152,7 @@
 
     /** Returns the bounded stack scroll */
     float getBoundedStackScroll(float scroll) {
-        return Math.max(mLayoutAlgorithm.mMinScrollP,
-                Math.min(mLayoutAlgorithm.mMaxScrollP, scroll));
+        return Utilities.clamp(scroll, mLayoutAlgorithm.mMinScrollP, mLayoutAlgorithm.mMaxScrollP);
     }
 
     /** Returns the amount that the absolute value of how much the scroll is out of bounds. */
@@ -191,21 +192,27 @@
         stopScroller();
         stopBoundScrollAnimation();
 
-        mFinalAnimatedScroll = newScroll;
-        mScrollAnimator = ObjectAnimator.ofFloat(this, STACK_SCROLL, getStackScroll(), newScroll);
-        mScrollAnimator.setDuration(mContext.getResources().getInteger(
-                R.integer.recents_animate_task_stack_scroll_duration));
-        mScrollAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        mScrollAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (postRunnable != null) {
-                    postRunnable.run();
+        if (Float.compare(mStackScrollP, newScroll) != 0) {
+            mFinalAnimatedScroll = newScroll;
+            mScrollAnimator = ObjectAnimator.ofFloat(this, STACK_SCROLL, getStackScroll(), newScroll);
+            mScrollAnimator.setDuration(mContext.getResources().getInteger(
+                    R.integer.recents_animate_task_stack_scroll_duration));
+            mScrollAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+            mScrollAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (postRunnable != null) {
+                        postRunnable.run();
+                    }
+                    mScrollAnimator.removeAllListeners();
                 }
-                mScrollAnimator.removeAllListeners();
+            });
+            mScrollAnimator.start();
+        } else {
+            if (postRunnable != null) {
+                postRunnable.run();
             }
-        });
-        mScrollAnimator.start();
+        }
     }
 
     /** Aborts any current stack scrolls */
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 d6680fd..fe504fe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -28,12 +28,13 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.ViewDebug;
 import android.view.ViewParent;
-import android.view.animation.Animation;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
@@ -43,7 +44,6 @@
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
 import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
-import com.android.systemui.recents.misc.RectFEvaluator;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
@@ -58,8 +58,6 @@
 class TaskStackViewTouchHandler implements SwipeHelper.Callback {
 
     private static final int INACTIVE_POINTER_ID = -1;
-
-    private static final RectFEvaluator RECT_EVALUATOR = new RectFEvaluator();
     private static final Interpolator STACK_TRANSFORM_INTERPOLATOR =
             new PathInterpolator(0.73f, 0.33f, 0.42f, 0.85f);
 
@@ -70,6 +68,7 @@
     FlingAnimationUtils mFlingAnimUtils;
     ValueAnimator mScrollFlingAnimator;
 
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mIsScrolling;
     float mDownScrollP;
     int mDownX, mDownY;
@@ -230,6 +229,8 @@
                         if (parent != null) {
                             parent.requestDisallowInterceptTouchEvent(true);
                         }
+
+                        MetricsLogger.action(mSv.getContext(), MetricsEvent.OVERVIEW_SCROLL);
                     }
                 }
                 if (mIsScrolling) {
@@ -279,6 +280,9 @@
                                 mOverscrollSize);
                         mSv.invalidate();
                     }
+
+                    // Reset the focused task after the user has scrolled
+                    mSv.resetFocusedTask(mSv.getFocusedTask());
                 } else if (mActiveTaskView == null) {
                     // This tap didn't start on a task.
                     maybeHideRecentsFromBackgroundTap((int) ev.getX(), (int) ev.getY());
@@ -400,6 +404,7 @@
         mCurrentTasks = mSv.getStack().getStackTasks();
         MutableBoolean isFrontMostTask = new MutableBoolean(false);
         Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
+        TaskStackLayoutAlgorithm layoutAlgorithm = mSv.getStackAlgorithm();
         TaskStackViewScroller stackScroller = mSv.getScroller();
         if (anchorTask != null) {
             // Get the current set of task transforms
@@ -410,7 +415,7 @@
             float prevAnchorTaskScroll = 0;
             boolean pullStackForward = mCurrentTasks.size() > 0;
             if (pullStackForward) {
-                prevAnchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+                prevAnchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
             }
 
             // Calculate where the views would be without the deleting tasks
@@ -422,9 +427,9 @@
                 newStackScroll = stackScroller.getBoundedStackScroll(newStackScroll);
             } else if (pullStackForward) {
                 // Otherwise, offset the scroll by the movement of the anchor task
-                float anchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+                float anchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
                 float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
-                if (mSv.getStackAlgorithm().getFocusState() !=
+                if (layoutAlgorithm.getFocusState() !=
                         TaskStackLayoutAlgorithm.STATE_FOCUSED) {
                     // If we are focused, we don't want the front task to move, but otherwise, we
                     // allow the back task to move up, and the front task to move back
@@ -438,7 +443,8 @@
             mSv.bindVisibleTaskViews(newStackScroll);
 
             // Get the final set of task transforms (with task removed)
-            mSv.getLayoutTaskTransforms(newStackScroll, mCurrentTasks, mFinalTaskTransforms);
+            mSv.getLayoutTaskTransforms(newStackScroll, TaskStackLayoutAlgorithm.STATE_UNFOCUSED,
+                    mCurrentTasks, mFinalTaskTransforms);
 
             // Set the target to scroll towards upon dismissal
             mTargetStackScroll = newStackScroll;
@@ -447,7 +453,8 @@
              * Post condition: All views that will be visible as a part of the gesture are retrieved
              *                 and at their initial positions.  The stack is still at the current
              *                 scroll, but the layout is updated without the task currently being
-             *                 dismissed.
+             *                 dismissed.  The final layout is in the unfocused stack state, which
+             *                 will be applied when the current task is dismissed.
              */
         }
     }
@@ -471,6 +478,8 @@
         tv.setTouchEnabled(true);
         // Update the scroll to the final scroll position from onBeginDrag()
         mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+        // Update the focus state to the final focus state
+        mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
         // Remove the task view from the stack
         EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
         // Stop tracking this deletion animation
@@ -542,9 +551,13 @@
 
             mTmpTransform.copyFrom(fromTransform);
             // We only really need to interpolate the bounds, progress and translation
-            mTmpTransform.rect.set(RECT_EVALUATOR.evaluate(dismissFraction, fromTransform.rect,
-                    toTransform.rect));
-            mTmpTransform.p = fromTransform.p + (toTransform.p - fromTransform.p) * dismissFraction;
+            mTmpTransform.rect.set(Utilities.RECTF_EVALUATOR.evaluate(dismissFraction,
+                    fromTransform.rect, toTransform.rect));
+            mTmpTransform.dimAlpha = fromTransform.dimAlpha + (toTransform.dimAlpha -
+                    fromTransform.dimAlpha) * dismissFraction;
+            mTmpTransform.viewOutlineAlpha = fromTransform.viewOutlineAlpha +
+                    (toTransform.viewOutlineAlpha - fromTransform.viewOutlineAlpha) *
+                            dismissFraction;
             mTmpTransform.translationZ = fromTransform.translationZ +
                     (toTransform.translationZ - fromTransform.translationZ) * dismissFraction;
 
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 439d96f..0c78e6a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -31,13 +31,15 @@
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
-import android.util.IntProperty;
 import android.util.Property;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewDebug;
 import android.view.ViewOutlineProvider;
-import android.view.animation.AccelerateInterpolator;
+import android.widget.Toast;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
@@ -77,57 +79,71 @@
      * The dim overlay is generally calculated from the task progress, but occasionally (like when
      * launching) needs to be animated independently of the task progress.
      */
-    public static final Property<TaskView, Integer> DIM =
-            new IntProperty<TaskView>("dim") {
+    public static final Property<TaskView, Float> DIM_ALPHA =
+            new FloatProperty<TaskView>("dimAlpha") {
                 @Override
-                public void setValue(TaskView tv, int dim) {
-                    tv.setDim(dim);
-                }
-
-                @Override
-                public Integer get(TaskView tv) {
-                    return tv.getDim();
-                }
-            };
-
-    public static final Property<TaskView, Float> TASK_PROGRESS =
-            new FloatProperty<TaskView>("taskProgress") {
-                @Override
-                public void setValue(TaskView tv, float p) {
-                    tv.setTaskProgress(p);
+                public void setValue(TaskView tv, float dimAlpha) {
+                    tv.setDimAlpha(dimAlpha);
                 }
 
                 @Override
                 public Float get(TaskView tv) {
-                    return tv.getTaskProgress();
+                    return tv.getDimAlpha();
                 }
             };
 
-    float mTaskProgress;
-    float mMaxDimScale;
-    int mDimAlpha;
-    AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(3f);
+    /**
+     * The dim overlay is generally calculated from the task progress, but occasionally (like when
+     * launching) needs to be animated independently of the task progress.
+     */
+    public static final Property<TaskView, Float> VIEW_OUTLINE_ALPHA =
+            new FloatProperty<TaskView>("viewOutlineAlpha") {
+                @Override
+                public void setValue(TaskView tv, float alpha) {
+                    tv.getViewBounds().setAlpha(alpha);
+                }
+
+                @Override
+                public Float get(TaskView tv) {
+                    return tv.getViewBounds().getAlpha();
+                }
+            };
+
+    @ViewDebug.ExportedProperty(category="recents")
+    float mDimAlpha;
     PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
     Paint mDimLayerPaint = new Paint();
     float mActionButtonTranslationZ;
 
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="task_")
     Task mTask;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mTaskDataLoaded;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mClipViewInStack = true;
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mTouchExplorationEnabled;
+    @ViewDebug.ExportedProperty(category="recents")
+    boolean mIsDisabledInSafeMode;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="view_bounds_")
     AnimateableViewBounds mViewBounds;
 
     private AnimatorSet mTransformAnimation;
     private ArrayList<Animator> mTmpAnimators = new ArrayList<>();
 
     View mContent;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="thumbnail_")
     TaskViewThumbnail mThumbnailView;
+    @ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
     TaskViewHeader mHeaderView;
     View mActionButtonView;
     TaskViewCallbacks mCb;
 
+    @ViewDebug.ExportedProperty(category="recents")
     Point mDownTouchPos = new Point();
 
+    private Toast mDisabledAppToast;
+
     public TaskView(Context context) {
         this(context, null);
     }
@@ -144,9 +160,8 @@
         super(context, attrs, defStyleAttr, defStyleRes);
         RecentsConfiguration config = Recents.getConfiguration();
         Resources res = context.getResources();
-        mMaxDimScale = res.getInteger(R.integer.recents_max_task_stack_view_dim) / 255f;
         mViewBounds = new AnimateableViewBounds(this, res.getDimensionPixelSize(
-                R.dimen.recents_task_view_rounded_corners_radius));
+                R.dimen.recents_task_view_shadow_rounded_corners_radius));
         if (config.fakeShadows) {
             setBackground(new FakeShadowDrawable(res, config));
         }
@@ -250,8 +265,11 @@
         mTmpAnimators.clear();
         toTransform.applyToTaskView(this, mTmpAnimators, toAnimation, !config.fakeShadows);
         if (toAnimation.isImmediate()) {
-            if (Float.compare(getTaskProgress(), toTransform.p) != 0) {
-                setTaskProgress(toTransform.p);
+            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
+                setDimAlpha(toTransform.dimAlpha);
+            }
+            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
+                mViewBounds.setAlpha(toTransform.viewOutlineAlpha);
             }
             // Manually call back to the animator listener and update callback
             if (toAnimation.getListener() != null) {
@@ -262,9 +280,14 @@
             }
         } else {
             // Both the progress and the update are a function of the bounds movement of the task
-            if (Float.compare(getTaskProgress(), toTransform.p) != 0) {
-                ObjectAnimator anim = ObjectAnimator.ofFloat(this, TASK_PROGRESS, getTaskProgress(),
-                        toTransform.p);
+            if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
+                ObjectAnimator anim = ObjectAnimator.ofFloat(this, DIM_ALPHA, getDimAlpha(),
+                        toTransform.dimAlpha);
+                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+            }
+            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
+                ObjectAnimator anim = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
+                        mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
                 mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
             }
             if (updateCallback != null) {
@@ -282,7 +305,7 @@
     /** Resets this view's properties */
     void resetViewProperties() {
         cancelTransformAnimation();
-        setDim(0);
+        setDimAlpha(0);
         setVisibility(View.VISIBLE);
         getViewBounds().reset();
         getHeaderView().reset();
@@ -357,76 +380,57 @@
         }
     }
 
-    /** Sets the current task progress. */
-    public void setTaskProgress(float p) {
-        mTaskProgress = p;
-        mViewBounds.setAlpha(p);
-        updateDimFromTaskProgress();
-    }
-
     public TaskViewHeader getHeaderView() {
         return mHeaderView;
     }
 
-    /** Returns the current task progress. */
-    public float getTaskProgress() {
-        return mTaskProgress;
-    }
-
-    /** Returns the current dim. */
-    public void setDim(int dim) {
+    /**
+     * Sets the current dim.
+     */
+    public void setDimAlpha(float dimAlpha) {
         RecentsConfiguration config = Recents.getConfiguration();
 
-        mDimAlpha = dim;
+        int dimAlphaInt = (int) (dimAlpha * 255);
+        mDimAlpha = dimAlpha;
         if (config.useHardwareLayers) {
             // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
             if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
-                mDimColorFilter.setColor(Color.argb(mDimAlpha, 0, 0, 0));
+                mDimColorFilter.setColor(Color.argb(dimAlphaInt, 0, 0, 0));
                 mDimLayerPaint.setColorFilter(mDimColorFilter);
                 mContent.setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint);
             }
         } else {
-            float dimAlpha = mDimAlpha / 255.0f;
             mThumbnailView.setDimAlpha(dimAlpha);
             mHeaderView.setDimAlpha(dimAlpha);
         }
     }
 
-    /** Returns the current dim. */
-    public int getDim() {
+    /**
+     * Returns the current dim.
+     */
+    public float getDimAlpha() {
         return mDimAlpha;
     }
 
-    /** Animates the dim to the task progress. */
-    void animateDimToProgress(int duration, Animator.AnimatorListener animListener) {
+    /**
+     * Animates the dim to the given value.
+     */
+    void animateDimAlpha(float toDimAlpha, AnimationProps animation) {
         // Animate the dim into view as well
-        int toDim = getDimFromTaskProgress();
-        if (toDim != getDim()) {
-            ObjectAnimator anim = ObjectAnimator.ofInt(this, DIM, getDim(), toDim);
-            anim.setDuration(duration);
-            if (animListener != null) {
-                anim.addListener(animListener);
+        if (Float.compare(toDimAlpha, getDimAlpha()) != 0) {
+            Animator anim = animation.apply(AnimationProps.DIM_ALPHA, ObjectAnimator.ofFloat(this,
+                    DIM_ALPHA, getDimAlpha(), toDimAlpha));
+            if (animation.getListener() != null) {
+                anim.addListener(animation.getListener());
             }
             anim.start();
         } else {
-            animListener.onAnimationEnd(null);
+            if (animation.getListener() != null) {
+                animation.getListener().onAnimationEnd(null);
+            }
         }
     }
 
-    /** Compute the dim as a function of the scale of this view. */
-    int getDimFromTaskProgress() {
-        float x = mTaskProgress < 0
-                ? 1f
-                : mDimInterpolator.getInterpolation(1f - mTaskProgress);
-        float dim = mMaxDimScale * x;
-        return (int) (dim * 255);
-    }
-
-    /** Update the dim as a function of the scale of this view. */
-    void updateDimFromTaskProgress() {
-        setDim(getDimFromTaskProgress());
-    }
-
     /**
      * Explicitly sets the focused state of this task.
      */
@@ -513,15 +517,18 @@
     @Override
     public void onPrepareLaunchTargetForEnterAnimation() {
         // These values will be animated in when onStartLaunchTargetEnterAnimation() is called
-        setDim(0);
+        setDimAlpha(0);
         mActionButtonView.setAlpha(0f);
     }
 
     @Override
     public void onStartLaunchTargetEnterAnimation(int duration, boolean screenPinningEnabled,
             ReferenceCountedTrigger postAnimationTrigger) {
+        // Un-dim the view before/while launching the target
+        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT)
+                .setListener(postAnimationTrigger.decrementOnAnimationEnd());
         postAnimationTrigger.increment();
-        animateDimToProgress(duration, postAnimationTrigger.decrementOnAnimationEnd());
+        animateDimAlpha(0, animation);
 
         if (screenPinningEnabled) {
             showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
@@ -531,12 +538,9 @@
     @Override
     public void onStartLaunchTargetLaunchAnimation(int duration, boolean screenPinningRequested,
             ReferenceCountedTrigger postAnimationTrigger) {
-        if (mDimAlpha > 0) {
-            ObjectAnimator anim = ObjectAnimator.ofInt(this, DIM, getDim(), 0);
-            anim.setDuration(duration);
-            anim.setInterpolator(Interpolators.ALPHA_OUT);
-            anim.start();
-        }
+        // Un-dim the view before/while launching the target
+        AnimationProps animation = new AnimationProps(duration, Interpolators.ALPHA_OUT);
+        animateDimAlpha(0, animation);
 
         postAnimationTrigger.increment();
         hideActionButton(true /* fadeOut */, duration,
@@ -547,15 +551,17 @@
     /**** TaskCallbacks Implementation ****/
 
     public void onTaskBound(Task t) {
+        SystemServicesProxy ssp = Recents.getSystemServices();
         mTask = t;
         mTask.addCallback(this);
+        mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
     }
 
     @Override
     public void onTaskDataLoaded(Task task) {
         // Bind each of the views to the new task data
-        mThumbnailView.rebindToTask(mTask);
-        mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled);
+        mThumbnailView.rebindToTask(mTask, mIsDisabledInSafeMode);
+        mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
         mTaskDataLoaded = true;
     }
 
@@ -570,13 +576,24 @@
 
     @Override
     public void onTaskStackIdChanged() {
-        mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled);
+        mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
     }
 
     /**** View.OnClickListener Implementation ****/
 
     @Override
      public void onClick(final View v) {
+        if (mIsDisabledInSafeMode) {
+            Context context = getContext();
+            String msg = context.getString(R.string.recents_launch_disabled_message, mTask.title);
+            if (mDisabledAppToast != null) {
+                mDisabledAppToast.cancel();
+            }
+            mDisabledAppToast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
+            mDisabledAppToast.show();
+            return;
+        }
+
         boolean screenPinningRequested = false;
         if (v == mActionButtonView) {
             // Reset the translation of the action button before we animate it out
@@ -585,6 +602,9 @@
         }
         EventBus.getDefault().send(new LaunchTaskEvent(this, mTask, null, INVALID_STACK_ID,
                 screenPinningRequested));
+
+        MetricsLogger.action(v.getContext(), MetricsEvent.OVERVIEW_SELECT,
+                mTask.key.getComponent().toString());
     }
 
     /**** View.OnLongClickListener Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index c91a833..bb56a52 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -36,6 +36,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewAnimationUtils;
+import android.view.ViewDebug;
 import android.view.ViewStub;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -74,6 +75,8 @@
 
         private Paint mHighlightPaint = new Paint();
         private Paint mBackgroundPaint = new Paint();
+        private int mColor;
+        private float mDimAlpha;
 
         public HighlightColorDrawable() {
             mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
@@ -83,15 +86,19 @@
         }
 
         public void setColorAndDim(int color, float dimAlpha) {
-            mBackgroundPaint.setColor(color);
+            if (mColor != color || Float.compare(mDimAlpha, dimAlpha) != 0) {
+                mColor = color;
+                mDimAlpha = dimAlpha;
+                mBackgroundPaint.setColor(color);
 
-            ColorUtils.colorToHSL(color, mTmpHSL);
-            // TODO: Consider using the saturation of the color to adjust the lightness as well
-            mTmpHSL[2] = Math.min(1f,
-                    mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
-            mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));
+                ColorUtils.colorToHSL(color, mTmpHSL);
+                // TODO: Consider using the saturation of the color to adjust the lightness as well
+                mTmpHSL[2] = Math.min(1f,
+                        mTmpHSL[2] + HIGHLIGHT_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
+                mHighlightPaint.setColor(ColorUtils.HSLToColor(mTmpHSL));
 
-            invalidateSelf();
+                invalidateSelf();
+            }
         }
 
         @Override
@@ -121,6 +128,10 @@
         public int getOpacity() {
             return PixelFormat.OPAQUE;
         }
+
+        public int getColor() {
+            return mColor;
+        }
     }
 
     Task mTask;
@@ -139,9 +150,11 @@
     ProgressBar mFocusTimerIndicator;
 
     // Header drawables
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mTaskViewRect = new Rect();
     int mCornerRadius;
     int mHighlightHeight;
+    @ViewDebug.ExportedProperty(category="recents")
     float mDimAlpha;
     Drawable mLightDismissDrawable;
     Drawable mDarkDismissDrawable;
@@ -153,6 +166,7 @@
     Drawable mDarkInfoIcon;
     int mTaskBarViewLightTextColor;
     int mTaskBarViewDarkTextColor;
+    int mDisabledTaskBarBackgroundColor;
     int mMoveTaskTargetStackId = INVALID_STACK_ID;
 
     // Header background
@@ -195,6 +209,8 @@
         mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
         mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
         mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
+        mDisabledTaskBarBackgroundColor =
+                context.getColor(R.color.recents_task_bar_disabled_background_color);
 
         // Configure the background and dim
         mBackground = new HighlightColorDrawable();
@@ -331,17 +347,17 @@
      */
     void setDimAlpha(float dimAlpha) {
         mDimAlpha = dimAlpha;
-        updateBackgroundColor(dimAlpha);
+        updateBackgroundColor(mBackground.getColor(), dimAlpha);
     }
 
     /**
      * Updates the background and highlight colors for this header.
      */
-    private void updateBackgroundColor(float dimAlpha) {
+    private void updateBackgroundColor(int color, float dimAlpha) {
         if (mTask != null) {
-            mBackground.setColorAndDim(mTask.colorPrimary, dimAlpha);
+            mBackground.setColorAndDim(color, dimAlpha);
             // TODO: Consider using the saturation of the color to adjust the lightness as well
-            ColorUtils.colorToHSL(mTask.colorPrimary, mTmpHSL);
+            ColorUtils.colorToHSL(color, mTmpHSL);
             mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
             mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
             mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
@@ -350,12 +366,15 @@
     }
 
     /** Binds the bar view to the task */
-    public void rebindToTask(Task t, boolean touchExplorationEnabled) {
+    public void rebindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
         mTask = t;
 
         // If an activity icon is defined, then we use that as the primary icon to show in the bar,
         // otherwise, we fall back to the application icon
-        updateBackgroundColor(mDimAlpha);
+        int primaryColor = disabledInSafeMode
+                ? mDisabledTaskBarBackgroundColor
+                : t.colorPrimary;
+        updateBackgroundColor(primaryColor, mDimAlpha);
         if (t.icon != null) {
             mIconView.setImageDrawable(t.icon);
         }
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 f90951e..0fec9c3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -21,13 +21,17 @@
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.LightingColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.graphics.Shader;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewDebug;
 
 import com.android.systemui.R;
 import com.android.systemui.recents.model.Task;
@@ -39,27 +43,40 @@
  */
 public class TaskViewThumbnail extends View {
 
+
+    private static final ColorMatrix TMP_FILTER_COLOR_MATRIX = new ColorMatrix();
+    private static final ColorMatrix TMP_BRIGHTNESS_COLOR_MATRIX = new ColorMatrix();
+
     private Task mTask;
 
     // Drawing
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mThumbnailRect = new Rect();
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mTaskViewRect = new Rect();
     int mCornerRadius;
+    @ViewDebug.ExportedProperty(category="recents")
     float mDimAlpha;
     Matrix mScaleMatrix = new Matrix();
     Paint mDrawPaint = new Paint();
+    Paint mBgFillPaint = new Paint();
     BitmapShader mBitmapShader;
     LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0);
 
     // Task bar clipping, the top of this thumbnail can be clipped against the opaque header
     // bar that overlaps this thumbnail
     View mTaskBar;
+    @ViewDebug.ExportedProperty(category="recents")
     Rect mClipRect = new Rect();
 
     // Visibility optimization, if the thumbnail height is less than the height of the header
     // bar for the task view, then just mark this thumbnail view as invisible
+    @ViewDebug.ExportedProperty(category="recents")
     boolean mInvisible;
 
+    @ViewDebug.ExportedProperty(category="recents")
+    boolean mDisabledInSafeMode;
+
     public TaskViewThumbnail(Context context) {
         this(context, null);
     }
@@ -79,6 +96,7 @@
         mDrawPaint.setAntiAlias(true);
         mCornerRadius = getResources().getDimensionPixelSize(
                 R.dimen.recents_task_view_rounded_corners_radius);
+        mBgFillPaint.setColor(Color.WHITE);
     }
 
     /**
@@ -100,10 +118,39 @@
         if (mInvisible) {
             return;
         }
-        // Draw the thumbnail with the rounded corners
-        canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(),
-                mCornerRadius,
-                mCornerRadius, mDrawPaint);
+
+        int thumbnailHeight = (int) (((float) mTaskViewRect.width() / mThumbnailRect.width()) *
+                mThumbnailRect.height());
+        if (thumbnailHeight >= mTaskViewRect.height()) {
+            // The thumbnail fills the full task view bounds, so just draw it
+            canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(),
+                    mCornerRadius, mCornerRadius, mDrawPaint);
+        } else {
+            int count = 0;
+            if (thumbnailHeight > 0) {
+                // The thumbnail only covers part of the task view bounds, so fill in the
+                // non-thumbnail space with the default background color.  This is the equivalent of
+                // the GL border texture mode.
+                count = canvas.save();
+
+                // Since we only want the top corners to be rounded, draw slightly beyond the
+                // thumbnail height, but clip to the thumbnail height
+                canvas.clipRect(0, 0, mTaskViewRect.width(), thumbnailHeight, Region.Op.REPLACE);
+                canvas.drawRoundRect(0, 0, mTaskViewRect.width(), thumbnailHeight + mCornerRadius,
+                        mCornerRadius, mCornerRadius, mDrawPaint);
+            }
+
+            // In the remaining space, draw the background color
+            canvas.clipRect(0, thumbnailHeight, mTaskViewRect.width(), mTaskViewRect.height(),
+                    Region.Op.REPLACE);
+            canvas.drawRoundRect(0, Math.max(0, thumbnailHeight - mCornerRadius),
+                    mTaskViewRect.width(), mTaskViewRect.height(), mCornerRadius, mCornerRadius,
+                    mBgFillPaint);
+
+            if (thumbnailHeight > 0) {
+                canvas.restoreToCount(count);
+            }
+        }
     }
 
     /** Sets the thumbnail to a given bitmap. */
@@ -128,9 +175,27 @@
         }
         int mul = (int) ((1.0f - mDimAlpha) * 255);
         if (mBitmapShader != null) {
-            mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul));
-            mDrawPaint.setColorFilter(mLightingColorFilter);
-            mDrawPaint.setColor(0xffffffff);
+            if (mDisabledInSafeMode) {
+                // Brightness: C-new = C-old*(1-amount) + amount
+                TMP_FILTER_COLOR_MATRIX.setSaturation(0);
+                float scale = 1f - mDimAlpha;
+                float[] mat = TMP_BRIGHTNESS_COLOR_MATRIX.getArray();
+                mat[0] = scale;
+                mat[6] = scale;
+                mat[12] = scale;
+                mat[4] = mDimAlpha;
+                mat[9] = mDimAlpha;
+                mat[14] = mDimAlpha;
+                TMP_FILTER_COLOR_MATRIX.preConcat(TMP_BRIGHTNESS_COLOR_MATRIX);
+                ColorMatrixColorFilter filter = new ColorMatrixColorFilter(TMP_FILTER_COLOR_MATRIX);
+                mDrawPaint.setColorFilter(filter);
+                mBgFillPaint.setColorFilter(filter);
+            } else {
+                mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul));
+                mDrawPaint.setColorFilter(mLightingColorFilter);
+                mDrawPaint.setColor(0xFFffffff);
+                mBgFillPaint.setColorFilter(mLightingColorFilter);
+            }
         } else {
             int grey = mul;
             mDrawPaint.setColorFilter(null);
@@ -196,10 +261,14 @@
     }
 
     /** Binds the thumbnail view to the task */
-    void rebindToTask(Task t) {
+    void rebindToTask(Task t, boolean disabledInSafeMode) {
         mTask = t;
+        mDisabledInSafeMode = disabledInSafeMode;
         if (t.thumbnail != null) {
             setThumbnail(t.thumbnail);
+            if (t.colorBackground != 0) {
+                mBgFillPaint.setColor(t.colorBackground);
+            }
         } else {
             setThumbnail(null);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index 32878b0..0d16a79 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -86,13 +86,11 @@
     public float translationZ = 0;
     public float scale = 1f;
     public float alpha = 1f;
+    public float dimAlpha = 0f;
+    public float viewOutlineAlpha = 0f;
 
     public boolean visible = false;
 
-    // This is the relative task progress of this task, relative to the stack scroll at which this
-    // transform was computed
-    public float p = 0f;
-
     // This is a window-space rect used for positioning the task in the stack and freeform workspace
     public RectF rect = new RectF();
 
@@ -104,7 +102,8 @@
         scale = tv.getScaleX();
         alpha = tv.getAlpha();
         visible = true;
-        p = tv.getTaskProgress();
+        dimAlpha = tv.getDimAlpha();
+        viewOutlineAlpha = tv.getViewBounds().getAlpha();
         rect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
     }
 
@@ -116,7 +115,8 @@
         scale = other.scale;
         alpha = other.alpha;
         visible = other.visible;
-        p = other.p;
+        dimAlpha = other.dimAlpha;
+        viewOutlineAlpha = other.viewOutlineAlpha;
         rect.set(other.rect);
     }
 
@@ -127,9 +127,10 @@
         translationZ = 0;
         scale = 1f;
         alpha = 1f;
+        dimAlpha = 0f;
+        viewOutlineAlpha = 0f;
         visible = false;
         rect.setEmpty();
-        p = 0f;
     }
 
     /** Convenience functions to compare against current property values */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
index 31fbd3e..a287fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
@@ -29,8 +29,8 @@
     /* An interface to the consumer of a view pool */
     public interface ViewPoolConsumer<V, T> {
         public V createView(Context context);
-        public void prepareViewToEnterPool(V v);
-        public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
+        public void onReturnViewToPool(V v);
+        public void onPickUpViewFromPool(V v, T prepareData, boolean isNewView);
         public boolean hasPreferredData(V v, T preferredData);
     }
 
@@ -46,7 +46,7 @@
 
     /** Returns a view into the pool */
     void returnViewToPool(V v) {
-        mViewCreator.prepareViewToEnterPool(v);
+        mViewCreator.onReturnViewToPool(v);
         mPool.push(v);
     }
 
@@ -73,7 +73,7 @@
                 v = mPool.pop();
             }
         }
-        mViewCreator.prepareViewToLeavePool(v, prepareData, isNewView);
+        mViewCreator.onPickUpViewFromPool(v, prepareData, isNewView);
         return v;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
index 12e2713..36cfac8 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
@@ -73,6 +73,7 @@
     private int mCurrentWidth;
     private int mCurrentHeight;
     private AnimatorSet mAnimator;
+    private boolean mTouching;
 
     public DividerHandleView(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
@@ -86,6 +87,9 @@
     }
 
     public void setTouching(boolean touching, boolean animate) {
+        if (touching == mTouching) {
+            return;
+        }
         if (mAnimator != null) {
             mAnimator.cancel();
             mAnimator = null;
@@ -103,6 +107,7 @@
             animateToTarget(touching ? mCircleDiameter : mWidth,
                     touching ? mCircleDiameter : mHeight, touching);
         }
+        mTouching = touching;
     }
 
     private void animateToTarget(int targetWidth, int targetHeight, boolean touching) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 83c22b1..1bdf5a1 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -100,6 +100,7 @@
     private final int[] mTempInt2 = new int[2];
     private boolean mMoving;
     private int mTouchSlop;
+    private boolean mBackgroundLifted;
 
     private int mDividerInsets;
     private int mDisplayWidth;
@@ -210,8 +211,8 @@
         mDockSide = mWindowManagerProxy.getDockSide();
         initializeSnapAlgorithm();
         mWindowManagerProxy.setResizing(true);
-        mWindowManager.setSlippery(false);
         if (touching) {
+            mWindowManager.setSlippery(false);
             liftBackground();
         }
         return mDockSide != WindowManager.DOCKED_INVALID;
@@ -389,6 +390,9 @@
     }
 
     private void liftBackground() {
+        if (mBackgroundLifted) {
+            return;
+        }
         if (isHorizontalDivision()) {
             mBackground.animate().scaleY(1.4f);
         } else {
@@ -407,9 +411,13 @@
                 .setDuration(TOUCH_ANIMATION_DURATION)
                 .translationZ(mTouchElevation)
                 .start();
+        mBackgroundLifted = true;
     }
 
     private void releaseBackground() {
+        if (!mBackgroundLifted) {
+            return;
+        }
         mBackground.animate()
                 .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                 .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
@@ -422,6 +430,7 @@
                 .setDuration(TOUCH_RELEASE_ANIMATION_DURATION)
                 .translationZ(0)
                 .start();
+        mBackgroundLifted = false;
     }
 
     @Override
@@ -485,7 +494,9 @@
         }
 
         // Make sure shadows are updated
-        mBackground.invalidate();
+        if (mBackground.getZ() > 0f) {
+            mBackground.invalidate();
+        }
 
         mLastResizeRect.set(mDockedRect);
         if (taskPosition != TASK_POSITION_SAME) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7d37ad2..2bebac2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -38,6 +38,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.os.AsyncTask;
@@ -116,7 +117,7 @@
         ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
         ExpandableNotificationRow.OnExpandClickListener {
     public static final String TAG = "StatusBar";
-    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    public static final boolean DEBUG = false;
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_REMOTE_INPUT =
@@ -194,6 +195,7 @@
     private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
 
     private UserManager mUserManager;
+    private int mDensity;
 
     // UI-specific methods
 
@@ -227,6 +229,7 @@
     protected int mState;
     protected boolean mBouncerShowing;
     protected boolean mShowLockscreenNotifications;
+    protected boolean mAllowLockscreenRemoteInput;
 
     protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
     protected DismissView mDismissView;
@@ -398,11 +401,26 @@
                 }
                 p = p.getParent();
             }
+            ExpandableNotificationRow row = null;
+            while (p != null) {
+                if (p instanceof ExpandableNotificationRow) {
+                    row = (ExpandableNotificationRow) p;
+                    break;
+                }
+                p = p.getParent();
+            }
 
-            if (riv == null) {
+            if (riv == null || row == null) {
                 return false;
             }
 
+            row.setUserExpanded(true);
+
+            if (isLockscreenPublicMode() && !mAllowLockscreenRemoteInput) {
+                onLockedRemoteInput(row, view);
+                return true;
+            }
+
             riv.setVisibility(View.VISIBLE);
             int cx = view.getLeft() + view.getWidth() / 2;
             int cy = view.getTop() + view.getHeight() / 2;
@@ -617,6 +635,10 @@
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
                 mSettingsObserver,
                 UserHandle.USER_ALL);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT), false,
+                mSettingsObserver,
+                UserHandle.USER_ALL);
 
         mContext.getContentResolver().registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
@@ -633,18 +655,22 @@
         mLocale = currentConfig.locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
         mFontScale = currentConfig.fontScale;
+        mDensity = currentConfig.densityDpi;
 
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
 
         // Connect in to the status bar manager service
         mCommandQueue = new CommandQueue(this);
 
-        int[] switches = new int[8];
+        int[] switches = new int[9];
         ArrayList<IBinder> binders = new ArrayList<IBinder>();
         ArrayList<String> iconSlots = new ArrayList<>();
         ArrayList<StatusBarIcon> icons = new ArrayList<>();
+        Rect fullscreenStackBounds = new Rect();
+        Rect dockedStackBounds = new Rect();
         try {
-            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders);
+            mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
+                    fullscreenStackBounds, dockedStackBounds);
         } catch (RemoteException ex) {
             // If the system process isn't there we're doomed anyway.
         }
@@ -653,7 +679,8 @@
 
         mSettingsObserver.onChange(false); // set up
         disable(switches[0], switches[6], false /* animate */);
-        setSystemUiVisibility(switches[1], 0xffffffff);
+        setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
+                fullscreenStackBounds, dockedStackBounds);
         topAppWindowChanged(switches[2] != 0);
         // StatusBarManagerService has a back up of IME token and it's restored here.
         setImeWindowStatus(binders.get(0), switches[3], switches[4], switches[5] != 0);
@@ -813,8 +840,13 @@
         final Locale locale = mContext.getResources().getConfiguration().locale;
         final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
         final float fontScale = newConfig.fontScale;
-
-        if (! locale.equals(mLocale) || ld != mLayoutDirection || fontScale != mFontScale) {
+        final int density = newConfig.densityDpi;
+        if (density != mDensity || mFontScale != fontScale) {
+            reInflateViews();
+            mDensity = density;
+            mFontScale = fontScale;
+        }
+        if (! locale.equals(mLocale) || ld != mLayoutDirection) {
             if (DEBUG) {
                 Log.v(TAG, String.format(
                         "config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
@@ -826,6 +858,21 @@
         }
     }
 
+    protected void reInflateViews() {
+        ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+        for (int i = 0; i < activeNotifications.size(); i++) {
+            Entry entry = activeNotifications.get(i);
+            boolean exposedGuts = entry.row.getGuts() == mNotificationGutsExposed;
+            entry.row.reInflateViews();
+            if (exposedGuts) {
+                mNotificationGutsExposed = entry.row.getGuts();
+                bindGuts(entry.row);
+            }
+            entry.cacheContentViews(mContext, null /* updatedNotification */);
+            inflateViews(entry, mStackScroller);
+        }
+    }
+
     protected View bindVetoButtonClickListener(View row, StatusBarNotification n) {
         View vetoButton = row.findViewById(R.id.veto);
         final String _pkg = n.getPackageName();
@@ -1273,6 +1320,8 @@
         }
     }
 
+    protected void onLockedRemoteInput(ExpandableNotificationRow row, View clickedView) {}
+
     @Override
     public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
     }
@@ -1909,6 +1958,10 @@
         mShowLockscreenNotifications = show;
     }
 
+    protected void setLockScreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
+        mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
+    }
+
     private void updateLockscreenNotificationSetting() {
         final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
@@ -1918,7 +1971,14 @@
                 null /* admin */, mCurrentUserId);
         final boolean allowedByDpm = (dpmFlags
                 & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
+
+        final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
+                0,
+                mCurrentUserId) != 0;
+
         setShowLockscreenNotifications(show && allowedByDpm);
+        setLockScreenAllowRemoteInput(remoteInput);
     }
 
     protected abstract void setAreThereNotifications();
@@ -2080,8 +2140,25 @@
             return false;
         }
 
-        if (isSnoozedPackage(sbn)) {
-            if (DEBUG) Log.d(TAG, "No peeking: snoozed package: " + sbn.getKey());
+        boolean inUse = mPowerManager.isScreenOn()
+                && (!mStatusBarKeyguardViewManager.isShowing()
+                || mStatusBarKeyguardViewManager.isOccluded())
+                && !mStatusBarKeyguardViewManager.isInputRestricted();
+        try {
+            inUse = inUse && !mDreamManager.isDreaming();
+        } catch (RemoteException e) {
+            Log.d(TAG, "failed to query dream manager", e);
+        }
+
+        if (!inUse) {
+            if (DEBUG) {
+                Log.d(TAG, "No peeking: not in use: " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
             return false;
         }
 
@@ -2090,15 +2167,17 @@
             return false;
         }
 
-        if (sbn.getNotification().fullScreenIntent != null
-                && mAccessibilityManager.isTouchExplorationEnabled()) {
-            if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
-            return false;
+        if (sbn.getNotification().fullScreenIntent != null) {
+            if (mAccessibilityManager.isTouchExplorationEnabled()) {
+                if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
+                return false;
+            } else {
+                return true;
+            }
         }
 
-
-        if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
-            if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+        if (isSnoozedPackage(sbn)) {
+            if (DEBUG) Log.d(TAG, "No peeking: snoozed package: " + sbn.getKey());
             return false;
         }
 
@@ -2107,17 +2186,7 @@
             return false;
         }
 
-        boolean inUse = mPowerManager.isScreenOn()
-                && (!mStatusBarKeyguardViewManager.isShowing()
-                        || mStatusBarKeyguardViewManager.isOccluded())
-                && !mStatusBarKeyguardViewManager.isInputRestricted();
-        try {
-            inUse = inUse && !mDreamManager.isDreaming();
-        } catch (RemoteException e) {
-            Log.d(TAG, "failed to query dream manager", e);
-        }
-        if (DEBUG) Log.d(TAG, "peek if device in use: " + inUse);
-        return inUse;
+        return true;
     }
 
     protected abstract boolean isSnoozedPackage(StatusBarNotification sbn);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 71347c4..3b960ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -17,12 +17,14 @@
 package com.android.systemui.statusbar;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.util.Pair;
 
+import com.android.internal.os.SomeArgs;
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
 
@@ -94,7 +96,8 @@
         public void animateExpandNotificationsPanel();
         public void animateCollapsePanels(int flags);
         public void animateExpandSettingsPanel(String obj);
-        public void setSystemUiVisibility(int vis, int mask);
+        public void setSystemUiVisibility(int vis, int fullscreenStackVis,
+                int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds);
         public void topAppWindowChanged(boolean visible);
         public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
                 boolean showImeSwitcher);
@@ -169,11 +172,19 @@
         }
     }
 
-    public void setSystemUiVisibility(int vis, int mask) {
+    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
+            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
         synchronized (mLock) {
             // Don't coalesce these, since it might have one time flags set such as
             // STATUS_BAR_UNHIDE which might get lost.
-            mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, vis, mask, null).sendToTarget();
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = vis;
+            args.argi2 = fullscreenStackVis;
+            args.argi3 = dockedStackVis;
+            args.argi4 = mask;
+            args.arg1 = fullscreenStackBounds;
+            args.arg2 = dockedStackBounds;
+            mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, args).sendToTarget();
         }
     }
 
@@ -377,7 +388,10 @@
                     mCallbacks.animateExpandSettingsPanel((String) msg.obj);
                     break;
                 case MSG_SET_SYSTEMUI_VISIBILITY:
-                    mCallbacks.setSystemUiVisibility(msg.arg1, msg.arg2);
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    mCallbacks.setSystemUiVisibility(args.argi1, args.argi2, args.argi3,
+                            args.argi4, (Rect) args.arg1, (Rect) args.arg2);
+                    args.recycle();
                     break;
                 case MSG_TOP_APP_WINDOW_CHANGED:
                     mCallbacks.topAppWindowChanged(msg.arg1 != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 7f1316f..7422902 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -25,6 +25,7 @@
 import android.os.Build;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -50,11 +51,11 @@
 
     private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
     private static final int COLORED_DIVIDER_ALPHA = 0x7B;
-    private final int mNotificationMinHeightLegacy;
-    private final int mMaxHeadsUpHeightLegacy;
-    private final int mMaxHeadsUpHeight;
-    private final int mNotificationMinHeight;
-    private final int mNotificationMaxHeight;
+    private int mNotificationMinHeightLegacy;
+    private int mMaxHeadsUpHeightLegacy;
+    private int mMaxHeadsUpHeight;
+    private int mNotificationMinHeight;
+    private int mNotificationMaxHeight;
 
     /** Does this row contain layouts that can adapt to row expansion */
     private boolean mExpandable;
@@ -507,6 +508,29 @@
         mHeadsUpManager = headsUpManager;
     }
 
+    public void reInflateViews() {
+        initDimens();
+        if (mIsSummaryWithChildren) {
+            removeView(mNotificationHeader);
+            mNotificationHeader = null;
+            recreateNotificationHeader();
+            if (mChildrenContainer != null) {
+                mChildrenContainer.reInflateViews();
+            }
+        }
+        if (mGuts != null) {
+            View oldGuts = mGuts;
+            int index = indexOfChild(oldGuts);
+            removeView(oldGuts);
+            mGuts = (NotificationGuts) LayoutInflater.from(mContext).inflate(
+                    R.layout.notification_guts, this, false);
+            mGuts.setVisibility(oldGuts.getVisibility());
+            addView(mGuts, index);
+        }
+        mPrivateLayout.reInflateViews();
+        mPublicLayout.reInflateViews();
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
@@ -514,6 +538,10 @@
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
         mFalsingManager = FalsingManager.getInstance(context);
+        initDimens();
+    }
+
+    private void initDimens() {
         mNotificationMinHeightLegacy =  getResources().getDimensionPixelSize(
                 R.dimen.notification_min_height_legacy);
         mNotificationMinHeight =  getResources().getDimensionPixelSize(
@@ -947,6 +975,10 @@
         }
     }
 
+    public boolean mustStayOnScreen() {
+        return mIsHeadsUp;
+    }
+
     private void updateClearability() {
         // public versions cannot be dismissed
         mVetoButton.setVisibility(isClearable() && !mShowingPublic ? View.VISIBLE : View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index a0fb34a..8042b60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -399,6 +399,10 @@
         return false;
     }
 
+    public boolean mustStayOnScreen() {
+        return false;
+    }
+
     /**
      * A listener notifying when {@link #getActualHeight} changes.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 76e522e..d5361dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -248,14 +248,16 @@
     public void reset(boolean resetActualHeight) {
         if (mContractedChild != null) {
             mContractedChild.animate().cancel();
+            removeView(mContractedChild);
         }
         if (mExpandedChild != null) {
             mExpandedChild.animate().cancel();
+            removeView(mExpandedChild);
         }
         if (mHeadsUpChild != null) {
             mHeadsUpChild.animate().cancel();
+            removeView(mHeadsUpChild);
         }
-        removeAllViews();
         mContractedChild = null;
         mExpandedChild = null;
         mHeadsUpChild = null;
@@ -494,7 +496,8 @@
                 return VISIBLE_TYPE_EXPANDED;
             }
         } else {
-            if (viewHeight <= mContractedChild.getHeight() || noExpandedChild) {
+            if (noExpandedChild || (viewHeight <= mContractedChild.getHeight()
+                    && (!mIsChildInGroup || !mContainingNotification.isExpanded()))) {
                 return VISIBLE_TYPE_CONTRACTED;
             } else {
                 return VISIBLE_TYPE_EXPANDED;
@@ -569,6 +572,9 @@
         if (mIsChildInGroup) {
             mSingleLineView = mHybridViewManager.bindFromNotification(
                     mSingleLineView, mStatusBarNotification.getNotification());
+        } else if (mSingleLineView != null) {
+            removeView(mSingleLineView);
+            mSingleLineView = null;
         }
     }
 
@@ -685,4 +691,12 @@
     public void requestSelectLayout(boolean needsAnimation) {
         selectLayout(needsAnimation, false);
     }
+
+    public void reInflateViews() {
+        if (mIsChildInGroup && mSingleLineView != null) {
+            removeView(mSingleLineView);
+            mSingleLineView = null;
+            updateSingleLineView();
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 5abd1d5..7346bec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -35,6 +35,8 @@
 import android.widget.SeekBar;
 import android.widget.TextView;
 
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 
@@ -51,6 +53,7 @@
     private SeekBar mSeekBar;
     private Notification.Topic mTopic;
     private INotificationManager mINotificationManager;
+    private int mStartingImportance;
 
     public NotificationGuts(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -103,21 +106,22 @@
 
     void bindImportance(final StatusBarNotification sbn, final ExpandableNotificationRow row,
             final int importance) {
+        mStartingImportance = importance;
         mINotificationManager = INotificationManager.Stub.asInterface(
                 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
         mTopic = sbn.getNotification().getTopic() == null
                 ? new Notification.Topic(Notification.TOPIC_DEFAULT, mContext.getString(
                 com.android.internal.R.string.default_notification_topic_label))
                 : sbn.getNotification().getTopic();
-        boolean doesAppUseTopics = false;
+        boolean doesUserUseTopics = false;
         try {
-            doesAppUseTopics =
-                    mINotificationManager.doesAppUseTopics(sbn.getPackageName(), sbn.getUid());
+            doesUserUseTopics =
+                    mINotificationManager.doesUserUseTopics(sbn.getPackageName(), sbn.getUid());
         } catch (RemoteException e) {}
-        final boolean appUsesTopics = doesAppUseTopics;
+        final boolean userUsesTopics = doesUserUseTopics;
 
         mApplyToTopic = (RadioButton) row.findViewById(R.id.apply_to_topic);
-        if (appUsesTopics) {
+        if (userUsesTopics) {
             mApplyToTopic.setChecked(true);
         }
         final View applyToApp = row.findViewById(R.id.apply_to_app);
@@ -151,7 +155,8 @@
                 }
                 updateTitleAndSummary(progress);
                 if (fromUser) {
-                    if (appUsesTopics) {
+                    MetricsLogger.action(mContext, MetricsEvent.ACTION_MODIFY_IMPORTANCE_SLIDER);
+                    if (userUsesTopics) {
                         mApplyToTopic.setVisibility(View.VISIBLE);
                         mApplyToTopic.setText(
                                 mContext.getString(R.string.apply_to_topic, mTopic.getLabel()));
@@ -205,6 +210,8 @@
 
     void saveImportance(final StatusBarNotification sbn) {
         int progress = mSeekBar.getProgress();
+        MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
+                progress - mStartingImportance);
         try {
             mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(),
                     mApplyToTopic.isChecked() ? mTopic : null, progress);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 6801e5f..9aa5ea0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -21,6 +21,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Drawable;
 import android.telephony.SubscriptionInfo;
@@ -80,6 +81,7 @@
     private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
     private int mIconTint = Color.WHITE;
     private float mDarkIntensity;
+    private final Rect mTintArea = new Rect();
 
     ViewGroup mEthernetGroup, mWifiGroup;
     View mNoSimsCombo;
@@ -490,23 +492,31 @@
         }
     }
 
-    public void setIconTint(int tint, float darkIntensity) {
-        boolean changed = tint != mIconTint || darkIntensity != mDarkIntensity;
+    public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
+        boolean changed = tint != mIconTint || darkIntensity != mDarkIntensity
+                || !mTintArea.equals(tintArea);
         mIconTint = tint;
         mDarkIntensity = darkIntensity;
+        mTintArea.set(tintArea);
         if (changed && isAttachedToWindow()) {
             applyIconTint();
         }
     }
 
     private void applyIconTint() {
-        setTint(mVpn, mIconTint);
-        setTint(mAirplane, mIconTint);
-        applyDarkIntensity(mDarkIntensity, mNoSims, mNoSimsDark);
-        applyDarkIntensity(mDarkIntensity, mWifi, mWifiDark);
-        applyDarkIntensity(mDarkIntensity, mEthernet, mEthernetDark);
+        setTint(mVpn, StatusBarIconController.getTint(mTintArea, mVpn, mIconTint));
+        setTint(mAirplane, StatusBarIconController.getTint(mTintArea, mAirplane, mIconTint));
+        applyDarkIntensity(
+                StatusBarIconController.getDarkIntensity(mTintArea, mNoSims, mDarkIntensity),
+                mNoSims, mNoSimsDark);
+        applyDarkIntensity(
+                StatusBarIconController.getDarkIntensity(mTintArea, mWifi, mDarkIntensity),
+                mWifi, mWifiDark);
+        applyDarkIntensity(
+                StatusBarIconController.getDarkIntensity(mTintArea, mEthernet, mDarkIntensity),
+                mEthernet, mEthernetDark);
         for (int i = 0; i < mPhoneStates.size(); i++) {
-            mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity);
+            mPhoneStates.get(i).setIconTint(mIconTint, mDarkIntensity, mTintArea);
         }
     }
 
@@ -613,9 +623,11 @@
             }
         }
 
-        public void setIconTint(int tint, float darkIntensity) {
-            applyDarkIntensity(darkIntensity, mMobile, mMobileDark);
-            setTint(mMobileType, tint);
+        public void setIconTint(int tint, float darkIntensity, Rect tintArea) {
+            applyDarkIntensity(
+                    StatusBarIconController.getDarkIntensity(tintArea, mMobile, darkIntensity),
+                    mMobile, mMobileDark);
+            setTint(mMobileType, StatusBarIconController.getTint(tintArea, mMobileType, tint));
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index e20936b..08cd053 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -109,6 +109,10 @@
         }
 
         @Override
+        public void onPinnedStackAnimationEnded() {
+        }
+
+        @Override
         public void onTaskStackChanged() {
             mHandler.removeCallbacks(this);
             mHandler.post(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 60c1911..aa001ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -45,4 +45,10 @@
             mInvertHelper.update(dark);
         }
     }
+
+    @Override
+    public void setVisible(boolean visible) {
+        super.setVisible(visible);
+        mView.setAlpha(visible ? 1.0f : 0.0f);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index a2b4c5d..328f8b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -105,6 +105,7 @@
 
     @Override
     public void setVisible(boolean visible) {
+        mView.animate().cancel();
         mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 5832d86..67d31be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -293,14 +293,19 @@
         mTransformedView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
         mTransformedView.setAlpha(visible ? 1.0f : 0.0f);
         if (visible) {
-            mTransformedView.setTranslationX(0);
-            mTransformedView.setTranslationY(0);
-            mTransformedView.setScaleX(1.0f);
-            mTransformedView.setScaleY(1.0f);
+            resetTransformedView();
         }
     }
 
     public void prepareFadeIn() {
+        resetTransformedView();
+    }
+
+    private void resetTransformedView() {
+        mTransformedView.setTranslationX(0);
+        mTransformedView.setTranslationY(0);
+        mTransformedView.setScaleX(1.0f);
+        mTransformedView.setScaleY(1.0f);
     }
 
     public static TransformState obtain() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index b5b7f43..33315c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -79,7 +79,8 @@
                 mTouchingHeadsUpView = false;
                 if (child instanceof ExpandableNotificationRow) {
                     mPickedChild = (ExpandableNotificationRow) child;
-                    mTouchingHeadsUpView = mPickedChild.isHeadsUp() && mPickedChild.isPinned();
+                    mTouchingHeadsUpView = !mStackScroller.isExpanded()
+                            && mPickedChild.isHeadsUp() && mPickedChild.isPinned();
                 }
                 break;
             case MotionEvent.ACTION_POINTER_UP:
@@ -106,7 +107,7 @@
                     mPanel.setPanelScrimMinFraction((float) expandedHeight
                             / mPanel.getMaxPanelHeight());
                     mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight);
-                    mPanel.clearNotificattonEffects();
+                    mPanel.clearNotificationEffects();
                     return true;
                 }
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightStatusBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightStatusBarController.java
new file mode 100644
index 0000000..f98b9e5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightStatusBarController.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.graphics.Rect;
+import android.view.View;
+
+import com.android.systemui.statusbar.policy.BatteryController;
+
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+
+/**
+ * Controls how light status bar flag applies to the icons.
+ */
+public class LightStatusBarController {
+
+    private final StatusBarIconController mIconController;
+    private final BatteryController mBatteryController;
+    private FingerprintUnlockController mFingerprintUnlockController;
+
+    private int mFullscreenStackVisibility;
+    private int mDockedStackVisibility;
+    private boolean mFullscreenLight;
+    private boolean mDockedLight;
+
+    private final Rect mLastFullscreenBounds = new Rect();
+    private final Rect mLastDockedBounds = new Rect();
+
+    public LightStatusBarController(StatusBarIconController iconController,
+            BatteryController batteryController) {
+        mIconController = iconController;
+        mBatteryController = batteryController;
+    }
+
+    public void setFingerprintUnlockController(
+            FingerprintUnlockController fingerprintUnlockController) {
+        mFingerprintUnlockController = fingerprintUnlockController;
+    }
+
+    public void onSystemUiVisibilityChanged(int fullscreenStackVis, int dockedStackVis, int mask,
+            Rect fullscreenStackBounds, Rect dockedStackBounds, boolean sbModeChanged,
+            int statusBarMode) {
+        int oldFullscreen = mFullscreenStackVisibility;
+        int newFullscreen = (oldFullscreen & ~mask) | (fullscreenStackVis & mask);
+        int diffFullscreen = newFullscreen ^ oldFullscreen;
+        int oldDocked = mDockedStackVisibility;
+        int newDocked = (oldDocked & ~mask) | (dockedStackVis & mask);
+        int diffDocked = newDocked ^ oldDocked;
+        if ((diffFullscreen & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
+                || (diffDocked & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
+                || sbModeChanged
+                || !mLastFullscreenBounds.equals(fullscreenStackBounds)
+                || !mLastDockedBounds.equals(dockedStackBounds)) {
+
+            mFullscreenLight = isLight(newFullscreen, statusBarMode);
+            mDockedLight = isLight(newDocked, statusBarMode);
+            update(fullscreenStackBounds, dockedStackBounds);
+        }
+        mFullscreenStackVisibility = newFullscreen;
+        mDockedStackVisibility = newDocked;
+        mLastFullscreenBounds.set(fullscreenStackBounds);
+        mLastDockedBounds.set(dockedStackBounds);
+    }
+
+    private boolean isLight(int vis, int statusBarMode) {
+        boolean isTransparentBar = (statusBarMode == MODE_TRANSPARENT
+                || statusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
+        boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
+        boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
+        return allowLight && light;
+    }
+
+    private boolean animateChange() {
+        if (mFingerprintUnlockController == null) {
+            return false;
+        }
+        int unlockMode = mFingerprintUnlockController.getMode();
+        return unlockMode != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+                && unlockMode != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
+    }
+
+    private void update(Rect fullscreenStackBounds, Rect dockedStackBounds) {
+        boolean hasDockedStack = !dockedStackBounds.isEmpty();
+
+        // If both are light or fullscreen is light and there is no docked stack, all icons get
+        // dark.
+        if ((mFullscreenLight && mDockedLight) || (mFullscreenLight && !hasDockedStack)) {
+            mIconController.setIconsDarkArea(null);
+            mIconController.setIconsDark(true, animateChange());
+
+        }
+
+        // If no one is light or the fullscreen is not light and there is no docked stack,
+        // all icons become white.
+        else if ((!mFullscreenLight && !mDockedLight) || (!mFullscreenLight && !hasDockedStack)) {
+            mIconController.setIconsDark(false, animateChange());
+
+        }
+
+        // Not the same for every stack, magic!
+        else {
+            Rect bounds = mFullscreenLight ? fullscreenStackBounds : dockedStackBounds;
+            if (bounds.isEmpty()) {
+                mIconController.setIconsDarkArea(null);
+            } else {
+                mIconController.setIconsDarkArea(bounds);
+            }
+            mIconController.setIconsDark(true, animateChange());
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 5f5974e..97d7dd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -496,8 +496,6 @@
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
-        updateRTLOrder();
-
         try {
             WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(new Stub() {
                 @Override
@@ -590,7 +588,6 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         boolean uiCarModeChanged = updateCarMode(newConfig);
-        updateRTLOrder();
         updateTaskSwitchHelper();
         if (uiCarModeChanged) {
             // uiMode changed either from carmode or to carmode.
@@ -618,59 +615,6 @@
         return uiCarModeChanged;
     }
 
-    /**
-     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
-     * have to do it manually
-     */
-    private void updateRTLOrder() {
-        boolean isLayoutRtl = getResources().getConfiguration()
-                .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        if (mIsLayoutRtl != isLayoutRtl) {
-
-            // We swap all children of the 90 and 270 degree layouts, since they are vertical
-            View rotation90 = mRotatedViews[Surface.ROTATION_90];
-            swapChildrenOrderIfVertical(rotation90);
-
-            View rotation270 = mRotatedViews[Surface.ROTATION_270];
-            if (rotation90 != rotation270) {
-                swapChildrenOrderIfVertical(rotation270);
-            }
-            mIsLayoutRtl = isLayoutRtl;
-        }
-    }
-
-    /**
-     * Swaps the children order of a LinearLayout if it's orientation is Vertical
-     *
-     * @param group The LinearLayout to swap the children from.
-     */
-    private void swapChildrenOrderIfVertical(View group) {
-        if (group instanceof LinearLayout) {
-            LinearLayout linearLayout = (LinearLayout) group;
-            if (linearLayout.getOrientation() == VERTICAL) {
-                if ((linearLayout.getGravity() & Gravity.TOP) != 0) {
-                    linearLayout.setGravity(Gravity.BOTTOM);
-                } else if ((linearLayout.getGravity() & Gravity.BOTTOM) != 0) {
-                    linearLayout.setGravity(Gravity.TOP);
-                }
-                int childCount = linearLayout.getChildCount();
-                ArrayList<View> childList = new ArrayList<>(childCount);
-                for (int i = 0; i < childCount; i++) {
-                    childList.add(linearLayout.getChildAt(i));
-                }
-                linearLayout.removeAllViews();
-                for (int i = childCount - 1; i >= 0; i--) {
-                    linearLayout.addView(childList.get(i));
-                }
-            }
-        } else if (group instanceof ViewGroup) {
-            ViewGroup viewGroup = (ViewGroup) group;
-            for (int i = 0; i < viewGroup.getChildCount(); i++) {
-                swapChildrenOrderIfVertical(viewGroup.getChildAt(i));
-            }
-        }
-    }
-
     /*
     @Override
     protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
@@ -738,9 +682,9 @@
                 + (offscreen ? " OFFSCREEN!" : ""));
 
         pw.println(String.format("      mCurrentView: id=%s (%dx%d) %s",
-                        getResourceName(mCurrentView.getId()),
-                        mCurrentView.getWidth(), mCurrentView.getHeight(),
-                        visibilityToString(mCurrentView.getVisibility())));
+                        getResourceName(getCurrentView().getId()),
+                        getCurrentView().getWidth(), getCurrentView().getHeight(),
+                        visibilityToString(getCurrentView().getVisibility())));
 
         pw.println(String.format("      disabled=0x%08x vertical=%s menu=%s",
                         mDisabledFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 03a597c..6e345f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -4,6 +4,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
@@ -32,6 +33,7 @@
     protected View mNotificationIconArea;
     private IconMerger mNotificationIcons;
     private ImageView mMoreIcon;
+    private final Rect mTintArea = new Rect();
 
     public NotificationIconAreaController(Context context, PhoneStatusBar phoneStatusBar) {
         mPhoneStatusBar = phoneStatusBar;
@@ -67,6 +69,20 @@
     }
 
     /**
+     * See {@link StatusBarIconController#setIconsDarkArea}.
+     *
+     * @param tintArea the area in which to tint the icons, specified in screen coordinates
+     */
+    public void setTintArea(Rect tintArea) {
+        if (tintArea == null) {
+            mTintArea.setEmpty();
+        } else {
+            mTintArea.set(tintArea);
+        }
+        applyNotificationIconsTint();
+    }
+
+    /**
      * Sets the color that should be used to tint any icons in the notification area. If this
      * method is not called, the default tint is {@link Color#WHITE}.
      */
@@ -145,7 +161,8 @@
             boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L));
             boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
             if (colorize) {
-                v.setImageTintList(ColorStateList.valueOf(mIconTint));
+                v.setImageTintList(ColorStateList.valueOf(
+                        StatusBarIconController.getTint(mTintArea, v, mIconTint)));
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index f822bd5..1a0acbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -19,7 +19,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
 import android.app.StatusBarManager;
@@ -35,13 +34,11 @@
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
-import android.view.ViewStub;
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.DejankUtils;
@@ -51,7 +48,6 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.qs.QSContainer;
-import com.android.systemui.qs.QSPanel;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -91,18 +87,15 @@
     public static final long DOZE_ANIMATION_DURATION = 700;
 
     private KeyguardAffordanceHelper mAfforanceHelper;
-    protected BaseStatusBarHeader mHeader;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
     private KeyguardStatusBarView mKeyguardStatusBar;
-    private QSContainer mQsContainer;
-    private QSPanel mQsPanel;
+    protected QSContainer mQsContainer;
     private KeyguardStatusView mKeyguardStatusView;
-    private ObservableScrollView mScrollView;
     private TextView mClockView;
     private View mReserveNotificationSpace;
     private View mQsNavbarScrim;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
-    private NotificationStackScrollLayout mNotificationStackScroller;
+    protected NotificationStackScrollLayout mNotificationStackScroller;
     private boolean mAnimateNextTopPaddingChange;
 
     private int mTrackingPointer;
@@ -133,9 +126,9 @@
     private float mInitialTouchY;
     private float mLastTouchX;
     private float mLastTouchY;
-    private float mQsExpansionHeight;
-    private int mQsMinExpansionHeight;
-    private int mQsMaxExpansionHeight;
+    protected float mQsExpansionHeight;
+    protected int mQsMinExpansionHeight;
+    protected int mQsMaxExpansionHeight;
     private int mQsPeekHeight;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
@@ -168,15 +161,12 @@
      * If we are in a panel collapsing motion, we reset scrollY of our scroll view but still
      * need to take this into account in our panel height calculation.
      */
-    private int mScrollYOverride = -1;
     private boolean mQsAnimatorExpand;
     private boolean mIsLaunchTransitionFinished;
     private boolean mIsLaunchTransitionRunning;
     private Runnable mLaunchAnimationEndRunnable;
     private boolean mOnlyAffordanceInThisMotion;
     private boolean mKeyguardStatusViewAnimating;
-    private boolean mHeaderAnimating;
-    private ObjectAnimator mQsContainerAnimator;
     private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShadeEmpty;
@@ -223,19 +213,11 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        ViewStub stub = (ViewStub) findViewById(R.id.status_bar_header);
-        stub.setLayoutResource(R.layout.quick_status_bar_expanded_header);
-        mHeader = (BaseStatusBarHeader) stub.inflate();
-        mHeader.setOnClickListener(this);
         mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
         mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
         mQsContainer = (QSContainer) findViewById(R.id.quick_settings_container);
-        mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
+        mQsContainer.getHeader().setOnClickListener(this);
         mClockView = (TextView) findViewById(R.id.clock_view);
-        mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
-        mScrollView.setListener(this);
-        mScrollView.setFocusable(false);
-        mReserveNotificationSpace = findViewById(R.id.reserve_notification_space);
         mNotificationContainerParent = (NotificationsQuickSettingsContainer)
                 findViewById(R.id.notification_container_parent);
         mNotificationStackScroller = (NotificationStackScrollLayout)
@@ -243,7 +225,7 @@
         mNotificationStackScroller.setOnHeightChangedListener(this);
         mNotificationStackScroller.setOverscrollTopChangedListener(this);
         mNotificationStackScroller.setOnEmptySpaceClickListener(this);
-        mNotificationStackScroller.setScrollView(mScrollView);
+        mNotificationStackScroller.setQsContainer(mQsContainer);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
         mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
         mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
@@ -285,12 +267,12 @@
     public void updateResources() {
         int panelWidth = getResources().getDimensionPixelSize(R.dimen.notification_panel_width);
         int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity);
-        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mHeader.getLayoutParams();
+        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mQsContainer.getLayoutParams();
         if (lp.width != panelWidth) {
             lp.width = panelWidth;
             lp.gravity = panelGravity;
-            mHeader.setLayoutParams(lp);
-            mHeader.post(mUpdateHeader);
+            mQsContainer.setLayoutParams(lp);
+            mQsContainer.post(mUpdateHeader);
         }
 
         lp = (FrameLayout.LayoutParams) mNotificationStackScroller.getLayoutParams();
@@ -299,13 +281,6 @@
             lp.gravity = panelGravity;
             mNotificationStackScroller.setLayoutParams(lp);
         }
-
-        lp = (FrameLayout.LayoutParams) mScrollView.getLayoutParams();
-        if (lp.width != panelWidth) {
-            lp.width = panelWidth;
-            lp.gravity = panelGravity;
-            mScrollView.setLayoutParams(lp);
-        }
     }
 
     @Override
@@ -318,8 +293,8 @@
 
         // Calculate quick setting heights.
         int oldMaxHeight = mQsMaxExpansionHeight;
-        mQsMinExpansionHeight = mKeyguardShowing ? 0 : mHeader.getCollapsedHeight() + mQsPeekHeight;
-        mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getDesiredHeight();
+        mQsMinExpansionHeight = mKeyguardShowing ? 0 : mQsContainer.getHeader().getHeight();
+        mQsMaxExpansionHeight = mQsContainer.getDesiredHeight();
         positionClockAndNotifications();
         if (mQsExpanded && mQsFullyExpanded) {
             mQsExpansionHeight = mQsMaxExpansionHeight;
@@ -361,7 +336,7 @@
                 requestScrollerTopPaddingUpdate(false /* animate */);
                 requestPanelHeightUpdate();
                 int height = (int) mQsSizeChangeAnimator.getAnimatedValue();
-                mQsContainer.setHeightOverride(height - mHeader.getExpandedHeight());
+                mQsContainer.setHeightOverride(height);
             }
         });
         mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() {
@@ -381,7 +356,7 @@
         boolean animate = mNotificationStackScroller.isAddOrRemoveAnimationPending();
         int stackScrollerPadding;
         if (mStatusBarState != StatusBarState.KEYGUARD) {
-            int bottom = mHeader.getCollapsedHeight();
+            int bottom = mQsContainer.getHeader().getHeight();
             stackScrollerPadding = mStatusBarState == StatusBarState.SHADE
                     ? bottom + mQsPeekHeight
                     : mKeyguardStatusBar.getHeight();
@@ -485,7 +460,7 @@
 
     public void setQsExpansionEnabled(boolean qsExpansionEnabled) {
         mQsExpansionEnabled = qsExpansionEnabled;
-        mHeader.setClickable(qsExpansionEnabled);
+        mQsContainer.setHeaderClickable(qsExpansionEnabled);
     }
 
     @Override
@@ -676,17 +651,6 @@
         }
     }
 
-    @Override
-    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-
-        // Block request when interacting with the scroll view so we can still intercept the
-        // scrolling when QS is expanded.
-        if (mScrollView.isHandlingTouchEvent()) {
-            return;
-        }
-        super.requestDisallowInterceptTouchEvent(disallowIntercept);
-    }
-
     private void flingQsWithCurrentVelocity(float y, boolean isCancelMotionEvent) {
         float vel = getCurrentVelocity();
         final boolean expandsQs = flingExpandsQs(vel);
@@ -808,7 +772,7 @@
     }
 
     private boolean isInQsArea(float x, float y) {
-        return (x >= mScrollView.getX() && x <= mScrollView.getX() + mScrollView.getWidth()) &&
+        return (x >= mQsContainer.getX() && x <= mQsContainer.getX() + mQsContainer.getWidth()) &&
                 (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
                 || y <= mQsContainer.getY() + mQsContainer.getHeight());
     }
@@ -948,7 +912,7 @@
             amount = 0f;
         }
         float rounded = amount >= 1f ? amount : 0f;
-        mStackScrollerOverscrolling = rounded != 0f && isRubberbanded;
+        setOverScrolling(rounded != 0f && isRubberbanded);
         mQsExpansionFromOverscroll = rounded != 0f;
         mLastOverscroll = rounded;
         updateQsState();
@@ -964,12 +928,17 @@
                     @Override
                     public void run() {
                         mStackScrollerOverscrolling = false;
-                        mQsExpansionFromOverscroll = false;
+                        setOverScrolling(false);
                         updateQsState();
                     }
                 }, false /* isClick */);
     }
 
+    private void setOverScrolling(boolean overscrolling) {
+        mStackScrollerOverscrolling = overscrolling;
+        mQsContainer.setOverscrolling(overscrolling);
+    }
+
     private void onQsExpansionStarted() {
         onQsExpansionStarted(0);
     }
@@ -979,11 +948,7 @@
         cancelHeightAnimator();
 
         // Reset scroll position and apply that position to the expanded height.
-        float height = mQsExpansionHeight - mScrollView.getScrollY() - overscrollAmount;
-        if (mScrollView.getScrollY() != 0) {
-            mScrollYOverride = mScrollView.getScrollY();
-        }
-        mScrollView.scrollTo(0, 0);
+        float height = mQsExpansionHeight - overscrollAmount;
         setQsExpansion(height);
         requestPanelHeightUpdate();
     }
@@ -995,9 +960,7 @@
             updateQsState();
             requestPanelHeightUpdate();
             mFalsingManager.setQsExpanded(expanded);
-            mNotificationStackScroller.setInterceptDelegateEnabled(expanded);
             mStatusBar.setQsExpanded(expanded);
-            mQsPanel.setExpanded(expanded);
             mNotificationContainerParent.setQsExpanded(expanded);
         }
     }
@@ -1011,15 +974,18 @@
 
         mStatusBarState = statusBarState;
         mKeyguardShowing = keyguardShowing;
+        mQsContainer.setKeyguardShowing(mKeyguardShowing);
 
         if (goingToFullShade || (oldState == StatusBarState.KEYGUARD
                 && statusBarState == StatusBarState.SHADE_LOCKED)) {
             animateKeyguardStatusBarOut();
-            animateHeaderSlidingIn();
+            long delay = mStatusBarState == StatusBarState.SHADE_LOCKED
+                    ? 0 : mStatusBar.calculateGoingToFullShadeDelay();
+            mQsContainer.animateHeaderSlidingIn(delay);
         } else if (oldState == StatusBarState.SHADE_LOCKED
                 && statusBarState == StatusBarState.KEYGUARD) {
             animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
-            animateHeaderSlidingOut();
+            mQsContainer.animateHeaderSlidingOut();
         } else {
             mKeyguardStatusBar.setAlpha(1f);
             mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
@@ -1050,95 +1016,6 @@
         }
     };
 
-    private final Animator.AnimatorListener mAnimateHeaderSlidingInListener
-            = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mHeaderAnimating = false;
-            mQsContainerAnimator = null;
-            mQsContainer.removeOnLayoutChangeListener(mQsContainerAnimatorUpdater);
-        }
-    };
-
-    private final OnLayoutChangeListener mQsContainerAnimatorUpdater
-            = new OnLayoutChangeListener() {
-        @Override
-        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-                int oldTop, int oldRight, int oldBottom) {
-            int oldHeight = oldBottom - oldTop;
-            int height = bottom - top;
-            if (height != oldHeight && mQsContainerAnimator != null) {
-                PropertyValuesHolder[] values = mQsContainerAnimator.getValues();
-                float newEndValue = mHeader.getCollapsedHeight() + mQsPeekHeight - height - top;
-                float newStartValue = -height - top;
-                values[0].setFloatValues(newStartValue, newEndValue);
-                mQsContainerAnimator.setCurrentPlayTime(mQsContainerAnimator.getCurrentPlayTime());
-            }
-        }
-    };
-
-    private final ViewTreeObserver.OnPreDrawListener mStartHeaderSlidingIn
-            = new ViewTreeObserver.OnPreDrawListener() {
-        @Override
-        public boolean onPreDraw() {
-            getViewTreeObserver().removeOnPreDrawListener(this);
-            long delay = mStatusBarState == StatusBarState.SHADE_LOCKED
-                    ? 0
-                    : mStatusBar.calculateGoingToFullShadeDelay();
-            mHeader.setTranslationY(-mHeader.getCollapsedHeight() - mQsPeekHeight);
-            mHeader.animate()
-                    .translationY(0f)
-                    .setStartDelay(delay)
-                    .setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE)
-                    .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                    .start();
-            mQsContainer.setY(-mQsContainer.getHeight());
-            mQsContainerAnimator = ObjectAnimator.ofFloat(mQsContainer, View.TRANSLATION_Y,
-                    mQsContainer.getTranslationY(),
-                    mHeader.getCollapsedHeight() + mQsPeekHeight - mQsContainer.getHeight()
-                            - mQsContainer.getTop());
-            mQsContainerAnimator.setStartDelay(delay);
-            mQsContainerAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
-            mQsContainerAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-            mQsContainerAnimator.addListener(mAnimateHeaderSlidingInListener);
-            mQsContainerAnimator.start();
-            mQsContainer.addOnLayoutChangeListener(mQsContainerAnimatorUpdater);
-            return true;
-        }
-    };
-
-    private void animateHeaderSlidingIn() {
-        // If the QS is already expanded we don't need to slide in the header as it's already
-        // visible.
-        if (!mQsExpanded) {
-            mHeaderAnimating = true;
-            getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
-        }
-    }
-
-    private void animateHeaderSlidingOut() {
-        mHeaderAnimating = true;
-        mHeader.animate().y(-mHeader.getHeight())
-                .setStartDelay(0)
-                .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .setListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        mHeader.animate().setListener(null);
-                        mHeaderAnimating = false;
-                        updateQsState();
-                    }
-                })
-                .start();
-        mQsContainer.animate()
-                .y(-mQsContainer.getHeight())
-                .setStartDelay(0)
-                .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD)
-                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                .start();
-    }
-
     private final Runnable mAnimateKeyguardStatusBarInvisibleEndRunnable = new Runnable() {
         @Override
         public void run() {
@@ -1195,8 +1072,8 @@
 
     private void setKeyguardBottomAreaVisibility(int statusBarState,
             boolean goingToFullShade) {
+        mKeyguardBottomArea.animate().cancel();
         if (goingToFullShade) {
-            mKeyguardBottomArea.animate().cancel();
             mKeyguardBottomArea.animate()
                     .alpha(0f)
                     .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
@@ -1206,13 +1083,11 @@
                     .start();
         } else if (statusBarState == StatusBarState.KEYGUARD
                 || statusBarState == StatusBarState.SHADE_LOCKED) {
-            mKeyguardBottomArea.animate().cancel();
             if (!mDozing) {
                 mKeyguardBottomArea.setVisibility(View.VISIBLE);
             }
             mKeyguardBottomArea.setAlpha(1f);
         } else {
-            mKeyguardBottomArea.animate().cancel();
             mKeyguardBottomArea.setVisibility(View.GONE);
             mKeyguardBottomArea.setAlpha(1f);
         }
@@ -1262,19 +1137,10 @@
     }
 
     private void updateQsState() {
-        boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling || mHeaderAnimating;
-        mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
-                ? View.VISIBLE
-                : View.INVISIBLE);
-        mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
-                || (mQsExpanded && !mStackScrollerOverscrolling));
+        mQsContainer.setExpanded(mQsExpanded);
         mNotificationStackScroller.setScrollingEnabled(
                 mStatusBarState != StatusBarState.KEYGUARD && (!mQsExpanded
                         || mQsExpansionFromOverscroll));
-        mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
-        mQsContainer.setVisibility(
-                mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE);
-        mScrollView.setTouchEnabled(mQsExpanded);
         updateEmptyShadeView();
         mQsNavbarScrim.setVisibility(mStatusBarState == StatusBarState.SHADE && mQsExpanded
                 && !mStackScrollerOverscrolling && mQsScrimEnabled
@@ -1298,11 +1164,10 @@
             }
         }
         mQsExpansionHeight = height;
-        mHeader.setExpansion(getHeaderExpansionFraction());
-        setQsTranslation(height);
+        updateQsExpansion();
         requestScrollerTopPaddingUpdate(false /* animate */);
         if (mKeyguardShowing) {
-            updateHeaderKeyguard();
+            updateHeaderKeyguardAlpha();
         }
         if (mStatusBarState == StatusBarState.SHADE_LOCKED
                 || mStatusBarState == StatusBarState.KEYGUARD) {
@@ -1329,6 +1194,10 @@
         }
     }
 
+    protected void updateQsExpansion() {
+        mQsContainer.setQsExpansion(getQsExpansionFraction(), getHeaderTranslation());
+    }
+
     private String getKeyguardOrLockScreenString() {
         if (mStatusBarState == StatusBarState.KEYGUARD) {
             return getContext().getString(R.string.accessibility_desc_lock_screen);
@@ -1337,23 +1206,6 @@
         }
     }
 
-    private float getHeaderExpansionFraction() {
-        if (!mKeyguardShowing) {
-            return getQsExpansionFraction();
-        } else {
-            return 1f;
-        }
-    }
-
-    private void setQsTranslation(float height) {
-        if (!mHeaderAnimating) {
-            mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation());
-        }
-        if (mKeyguardShowing && !mHeaderAnimating) {
-            mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0));
-        }
-    }
-
     private float calculateQsTopPadding() {
         if (mKeyguardShowing
                 && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
@@ -1372,7 +1224,7 @@
                     mQsMinExpansionHeight, max);
         } else if (mQsSizeChangeAnimator != null) {
             return (int) mQsSizeChangeAnimator.getAnimatedValue();
-        } else if (mKeyguardShowing && mScrollYOverride == -1) {
+        } else if (mKeyguardShowing) {
 
             // We can only do the smoother transition on Keyguard when we also are not collapsing
             // from a scrolled quick settings.
@@ -1384,9 +1236,8 @@
         }
     }
 
-    private void requestScrollerTopPaddingUpdate(boolean animate) {
+    protected void requestScrollerTopPaddingUpdate(boolean animate) {
         mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(),
-                mScrollView.getScrollY(),
                 mAnimateNextTopPaddingChange || animate,
                 mKeyguardShowing
                         && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted));
@@ -1428,7 +1279,6 @@
             boolean isClick) {
         float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight;
         if (target == mQsExpansionHeight) {
-            mScrollYOverride = -1;
             if (onFinishRunnable != null) {
                 onFinishRunnable.run();
             }
@@ -1438,7 +1288,6 @@
         if (belowFalsingThreshold) {
             vel = 0;
         }
-        mScrollView.setBlockFlinging(true);
         ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
         if (isClick) {
             animator.setInterpolator(Interpolators.TOUCH_RESPONSE);
@@ -1458,8 +1307,6 @@
         animator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mScrollView.setBlockFlinging(false);
-                mScrollYOverride = -1;
                 mQsExpansionAnimator = null;
                 if (onFinishRunnable != null) {
                     onFinishRunnable.run();
@@ -1478,11 +1325,11 @@
         if (!mQsExpansionEnabled || mCollapsedOnDown) {
             return false;
         }
-        View header = mKeyguardShowing ? mKeyguardStatusBar : mHeader;
+        View header = mKeyguardShowing ? mKeyguardStatusBar : mQsContainer.getHeader();
         boolean onHeader = x >= header.getX() && x <= header.getX() + header.getWidth()
                 && y >= header.getTop() && y <= header.getBottom();
         if (mQsExpanded) {
-            return onHeader || (mScrollView.isScrolledToBottom() && yDiff < 0) && isInQsArea(x, y);
+            return onHeader || (yDiff < 0 && isInQsArea(x, y));
         } else {
             return onHeader;
         }
@@ -1494,7 +1341,7 @@
             return mStatusBar.getBarState() == StatusBarState.KEYGUARD
                     || mNotificationStackScroller.isScrolledToBottom();
         } else {
-            return mScrollView.isScrolledToBottom();
+            return true;
         }
     }
 
@@ -1571,11 +1418,7 @@
      *         collapsing QS / the panel when QS was scrolled
      */
     private int getTempQsMaxExpansion() {
-        int qsTempMaxExpansion = mQsMaxExpansionHeight;
-        if (mScrollYOverride != -1) {
-            qsTempMaxExpansion -= mScrollYOverride;
-        }
-        return qsTempMaxExpansion;
+        return mQsMaxExpansionHeight;
     }
 
     private int calculatePanelHeightShade() {
@@ -1613,20 +1456,12 @@
                 + notificationHeight;
         if (totalHeight > mNotificationStackScroller.getHeight()) {
             float fullyCollapsedHeight = maxQsHeight
-                    + mNotificationStackScroller.getMinStackHeight()
-                    - getScrollViewScrollY();
+                    + mNotificationStackScroller.getMinStackHeight();
             totalHeight = Math.max(fullyCollapsedHeight, mNotificationStackScroller.getHeight());
         }
         return (int) totalHeight;
     }
 
-    private int getScrollViewScrollY() {
-        if (mScrollYOverride != -1 && !mQsTracking) {
-            return mScrollYOverride;
-        } else {
-            return mScrollView.getScrollY();
-        }
-    }
     private void updateNotificationTranslucency() {
         float alpha = 1f;
         if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && !mHeadsUpManager.hasPinnedHeadsUp()) {
@@ -1678,30 +1513,17 @@
      */
     private void updateHeader() {
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
-            updateHeaderKeyguard();
-        } else {
-            updateHeaderShade();
+            updateHeaderKeyguardAlpha();
         }
-
+        updateQsExpansion();
     }
 
-    private void updateHeaderShade() {
-        if (!mHeaderAnimating) {
-            mHeader.setTranslationY(getHeaderTranslation());
-        }
-        setQsTranslation(mQsExpansionHeight);
-    }
-
-    private float getHeaderTranslation() {
+    protected float getHeaderTranslation() {
         if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
             return 0;
         }
         if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
-            if (mExpandedHeight / HEADER_RUBBERBAND_FACTOR >= mQsMinExpansionHeight) {
-                return 0;
-            } else {
-                return mExpandedHeight / HEADER_RUBBERBAND_FACTOR - mQsMinExpansionHeight;
-            }
+            return Math.min(0, mExpandedHeight / HEADER_RUBBERBAND_FACTOR - mQsMinExpansionHeight);
         }
         float stackTranslation = mNotificationStackScroller.getStackTranslation();
         float translation = stackTranslation / HEADER_RUBBERBAND_FACTOR;
@@ -1744,11 +1566,6 @@
                 && !mDozing ? VISIBLE : INVISIBLE);
     }
 
-    private void updateHeaderKeyguard() {
-        updateHeaderKeyguardAlpha();
-        setQsTranslation(mQsExpansionHeight);
-    }
-
     private void updateKeyguardBottomAreaAlpha() {
         float alpha = Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction());
         mKeyguardBottomArea.setAlpha(alpha);
@@ -1781,7 +1598,6 @@
         mNotificationStackScroller.onExpansionStopped();
         mHeadsUpManager.onExpandingFinished();
         mIsExpanding = false;
-        mScrollYOverride = -1;
         if (isFullyCollapsed()) {
             DejankUtils.postAfterTraversal(new Runnable() {
                 @Override
@@ -1811,9 +1627,8 @@
     }
 
     private void setListening(boolean listening) {
-        mHeader.setListening(listening);
+        mQsContainer.setListening(listening);
         mKeyguardStatusBar.setListening(listening);
-        mQsPanel.setListening(listening);
     }
 
     @Override
@@ -1931,7 +1746,7 @@
 
     @Override
     public void onClick(View v) {
-        if (v == mHeader) {
+        if (v == mQsContainer.getHeader()) {
             onQsExpansionStarted();
             if (mQsExpanded) {
                 flingSettings(0 /* vel */, false /* expand */, null, true /* isClick */);
@@ -2149,24 +1964,16 @@
         return mConflictingQsExpansionGesture && mQsExpanded;
     }
 
-    public void notifyVisibleChildrenChanged() {
-        if (mNotificationStackScroller.getNotGoneChildCount() != 0) {
-            mReserveNotificationSpace.setVisibility(View.VISIBLE);
-        } else {
-            mReserveNotificationSpace.setVisibility(View.GONE);
-        }
-    }
-
     public boolean isQsExpanded() {
         return mQsExpanded;
     }
 
     public boolean isQsDetailShowing() {
-        return mQsPanel.isShowingDetail();
+        return mQsContainer.isShowingDetail();
     }
 
     public void closeQsDetail() {
-        mQsPanel.closeDetail();
+        mQsContainer.getQsPanel().closeDetail();
     }
 
     @Override
@@ -2254,7 +2061,7 @@
     private final Runnable mUpdateHeader = new Runnable() {
         @Override
         public void run() {
-            mHeader.updateEverything();
+            mQsContainer.getHeader().updateEverything();
         }
     };
 
@@ -2378,7 +2185,7 @@
      *
      * @param x the x-coordinate the touch event
      */
-    private void updateVerticalPanelPosition(float x) {
+    protected void updateVerticalPanelPosition(float x) {
         if (mNotificationStackScroller.getWidth() * 1.75f > getWidth()) {
             resetVerticalPanelPosition();
             return;
@@ -2400,11 +2207,10 @@
 
     protected void setVerticalPanelTranslation(float translation) {
         mNotificationStackScroller.setTranslationX(translation);
-        mScrollView.setTranslationX(translation);
-        mHeader.setTranslationX(translation);
+        mQsContainer.setTranslationX(translation);
     }
 
-    private void updateStackHeight(float stackHeight) {
+    protected void updateStackHeight(float stackHeight) {
         mNotificationStackScroller.setStackHeight(stackHeight);
         updateKeyguardBottomAreaAlpha();
     }
@@ -2413,7 +2219,7 @@
         mBar.panelScrimMinFractionChanged(minFraction);
     }
 
-    public void clearNotificattonEffects() {
+    public void clearNotificationEffects() {
         mStatusBar.clearNotificationEffects();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index fd28b09..7cc720d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -33,7 +33,7 @@
 public class NotificationsQuickSettingsContainer extends FrameLayout
         implements ViewStub.OnInflateListener {
 
-    private View mScrollView;
+    private View mQsContainer;
     private View mUserSwitcher;
     private View mStackScroller;
     private View mKeyguardStatusBar;
@@ -47,7 +47,7 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mScrollView = findViewById(R.id.scroll_view);
+        mQsContainer = findViewById(R.id.quick_settings_container);
         mStackScroller = findViewById(R.id.notification_stack_scroller);
         mKeyguardStatusBar = findViewById(R.id.keyguard_header);
         ViewStub userSwitcher = (ViewStub) findViewById(R.id.keyguard_user_switcher);
@@ -58,7 +58,7 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        reloadWidth(mScrollView);
+        reloadWidth(mQsContainer);
         reloadWidth(mStackScroller);
     }
 
@@ -80,11 +80,11 @@
         boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
         boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
 
-        View stackQsTop = mQsExpanded ? mStackScroller : mScrollView;
-        View stackQsBottom = !mQsExpanded ? mStackScroller : mScrollView;
+        View stackQsTop = mQsExpanded ? mStackScroller : mQsContainer;
+        View stackQsBottom = !mQsExpanded ? mStackScroller : mQsContainer;
         // Invert the order of the scroll view and user switcher such that the notifications receive
         // touches first but the panel gets drawn above.
-        if (child == mScrollView) {
+        if (child == mQsContainer) {
             return super.drawChild(canvas, userSwitcherVisible && statusBarVisible ? mUserSwitcher
                     : statusBarVisible ? mKeyguardStatusBar
                     : userSwitcherVisible ? mUserSwitcher
@@ -104,7 +104,7 @@
             return super.drawChild(canvas,
                     stackQsTop,
                     drawingTime);
-        }else {
+        } else {
             return super.drawChild(canvas, child, drawingTime);
         }
     }
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 09a7bf0..3aa576f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -95,7 +95,6 @@
 import android.view.animation.Interpolator;
 import android.widget.ImageView;
 import android.widget.TextView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.NotificationVisibility;
@@ -116,6 +115,7 @@
 import com.android.systemui.doze.DozeHost;
 import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.qs.QSDetail;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.recents.events.EventBus;
@@ -174,7 +174,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeSet;
 
 import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
 import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -265,7 +264,7 @@
                     IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
             onlyCoreApps = packageManager.isOnlyCoreApps();
             freeformWindowManagement = packageManager.hasSystemFeature(
-                    PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT);
+                    PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
         } catch (RemoteException e) {
             onlyCoreApps = false;
             freeformWindowManagement = false;
@@ -296,6 +295,7 @@
     BrightnessMirrorController mBrightnessMirrorController;
     AccessibilityController mAccessibilityController;
     FingerprintUnlockController mFingerprintUnlockController;
+    LightStatusBarController mLightStatusBarController;
 
     int mNaturalBarHeight = -1;
 
@@ -340,6 +340,9 @@
     private long mKeyguardFadingAwayDelay;
     private long mKeyguardFadingAwayDuration;
 
+    // RemoteInputView to be activated after unlock
+    private View mPendingRemoteInputView;
+
     int mMaxAllowedKeyguardNotifications;
 
     boolean mExpandedVisible;
@@ -361,6 +364,8 @@
 
     // tracking calls to View.setSystemUiVisibility()
     int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+    private final Rect mLastFullscreenStackBounds = new Rect();
+    private final Rect mLastDockedStackBounds = new Rect();
 
     // last value sent to window manager
     private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
@@ -519,7 +524,7 @@
      */
     protected boolean mStartedGoingToSleep;
 
-    private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD
+    private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_HUN
             | StackViewState.LOCATION_MAIN_AREA;
 
     private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
@@ -754,19 +759,8 @@
         mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
 
 
-        mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
-                R.layout.status_bar_no_notifications, mStackScroller, false);
-        mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
-                R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
-        mDismissView.setOnButtonClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
-                clearAllNotifications();
-            }
-        });
-        mStackScroller.setDismissView(mDismissView);
+        inflateEmptyShadeView();
+        inflateDismissView();
         mExpandedContents = mStackScroller;
 
         mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
@@ -855,6 +849,8 @@
         mAccessibilityController = new AccessibilityController(mContext);
         mKeyguardBottomArea.setAccessibilityController(mAccessibilityController);
         mNextAlarmController = new NextAlarmController(mContext);
+        mLightStatusBarController = new LightStatusBarController(mIconController,
+                mBatteryController);
         mKeyguardMonitor = new KeyguardMonitor(mContext);
         if (UserManager.get(mContext).isUserSwitcherEnabled()) {
             mUserSwitcherController = new UserSwitcherController(mContext, mKeyguardMonitor,
@@ -876,6 +872,8 @@
             mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
             mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
             mHeader.setQSPanel(mQSPanel);
+            QSDetail qsDetail = (QSDetail) mStatusBarWindow.findViewById(R.id.qs_detail);
+            qsDetail.setHost(qsh);
             qsh.addCallback(new QSTileHost.Callback() {
                 @Override
                 public void onTilesChanged() {
@@ -930,6 +928,34 @@
         return mStatusBarView;
     }
 
+    @Override
+    protected void reInflateViews() {
+        super.reInflateViews();
+        inflateDismissView();
+        updateClearAll();
+        inflateEmptyShadeView();
+        updateEmptyShadeView();
+    }
+
+    private void inflateEmptyShadeView() {
+        mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
+                R.layout.status_bar_no_notifications, mStackScroller, false);
+        mStackScroller.setEmptyShadeView(mEmptyShadeView);
+    }
+
+    private void inflateDismissView() {
+        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
+                R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
+        mDismissView.setOnButtonClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
+                clearAllNotifications();
+            }
+        });
+        mStackScroller.setDismissView(mDismissView);
+    }
+
     protected void createUserSwitcher() {
         mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
                 (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
@@ -1072,6 +1098,7 @@
         mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
         mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
+        mLightStatusBarController.setFingerprintUnlockController(mFingerprintUnlockController);
     }
 
     @Override
@@ -1483,8 +1510,8 @@
     }
 
     private void updateNotificationShadeForChildren() {
+        // First let's remove all children which don't belong in the parents
         ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
-        boolean orderChanged = false;
         for (int i = 0; i < mStackScroller.getChildCount(); i++) {
             View view = mStackScroller.getChildAt(i);
             if (!(view instanceof ExpandableNotificationRow)) {
@@ -1496,7 +1523,6 @@
             List<ExpandableNotificationRow> children = parent.getNotificationChildren();
             List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
 
-            // lets first remove all undesired children
             if (children != null) {
                 toRemove.clear();
                 for (ExpandableNotificationRow childRow : children) {
@@ -1509,8 +1535,21 @@
                     mStackScroller.notifyGroupChildRemoved(remove);
                 }
             }
+        }
 
-            // We now add all the children which are not in there already
+        // Let's now add all notification children which are missing
+        boolean orderChanged = false;
+        for (int i = 0; i < mStackScroller.getChildCount(); i++) {
+            View view = mStackScroller.getChildAt(i);
+            if (!(view instanceof ExpandableNotificationRow)) {
+                // We don't care about non-notification views.
+                continue;
+            }
+
+            ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
+            List<ExpandableNotificationRow> children = parent.getNotificationChildren();
+            List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
+
             for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
                     childIndex++) {
                 ExpandableNotificationRow childView = orderedChildren.get(childIndex);
@@ -1600,12 +1639,6 @@
     }
 
     @Override
-    protected void updateRowStates() {
-        super.updateRowStates();
-        mNotificationPanel.notifyVisibleChildrenChanged();
-    }
-
-    @Override
     protected void setAreThereNotifications() {
 
         if (SPEW) {
@@ -2227,7 +2260,7 @@
 
     @Override
     public void maybeEscalateHeadsUp() {
-        TreeSet<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getSortedEntries();
+        Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
         for (HeadsUpManager.HeadsUpEntry entry : entries) {
             final StatusBarNotification sbn = entry.entry.notification;
             final Notification notification = sbn.getNotification();
@@ -2513,7 +2546,8 @@
     }
 
     @Override // CommandQueue
-    public void setSystemUiVisibility(int vis, int mask) {
+    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
+            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
         final int oldVal = mSystemUiVisibility;
         final int newVal = (oldVal&~mask) | (vis&mask);
         final int diff = newVal ^ oldVal;
@@ -2522,6 +2556,7 @@
                 Integer.toHexString(vis), Integer.toHexString(mask),
                 Integer.toHexString(oldVal), Integer.toHexString(newVal),
                 Integer.toHexString(diff)));
+        boolean sbModeChanged = false;
         if (diff != 0) {
             // we never set the recents bit via this method, so save the prior state to prevent
             // clobbering the bit below
@@ -2555,7 +2590,7 @@
                     oldVal, newVal, mNavigationBarView.getBarTransitions(),
                     View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
                     View.NAVIGATION_BAR_TRANSPARENT);
-            final boolean sbModeChanged = sbMode != -1;
+            sbModeChanged = sbMode != -1;
             final boolean nbModeChanged = nbMode != -1;
             boolean checkBarModes = false;
             if (sbModeChanged && sbMode != mStatusBarMode) {
@@ -2582,18 +2617,6 @@
                 mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
             }
 
-            if ((diff & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0 || sbModeChanged) {
-                boolean isTransparentBar = (mStatusBarMode == MODE_TRANSPARENT
-                        || mStatusBarMode == MODE_LIGHTS_OUT_TRANSPARENT);
-                boolean allowLight = isTransparentBar && !mBatteryController.isPowerSave();
-                boolean light = (vis & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
-                boolean animate = mFingerprintUnlockController == null
-                        || (mFingerprintUnlockController.getMode()
-                                != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
-                        && mFingerprintUnlockController.getMode()
-                                != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
-                mIconController.setIconsDark(allowLight && light, animate);
-            }
             // restore the recents bit
             if (wasRecentsVisible) {
                 mSystemUiVisibility |= View.RECENT_APPS_VISIBLE;
@@ -2602,6 +2625,9 @@
             // send updated sysui visibility to window manager
             notifyUiVisibilityChanged(mSystemUiVisibility);
         }
+
+        mLightStatusBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
+                mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode);
     }
 
     private int computeBarMode(int oldVis, int newVis, BarTransitions transitions,
@@ -2729,9 +2755,12 @@
     public void setLightsOn(boolean on) {
         Log.v(TAG, "setLightsOn(" + on + ")");
         if (on) {
-            setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
+            setSystemUiVisibility(0, 0, 0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
+                    mLastFullscreenStackBounds, mLastDockedStackBounds);
         } else {
-            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, View.SYSTEM_UI_FLAG_LOW_PROFILE);
+            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE, 0, 0,
+                    View.SYSTEM_UI_FLAG_LOW_PROFILE, mLastFullscreenStackBounds,
+                    mLastDockedStackBounds);
         }
     }
 
@@ -3553,6 +3582,7 @@
             mDraggedDownRow.notifyHeightChanged(false  /* needsAnimation */);
             mDraggedDownRow = null;
         }
+        mPendingRemoteInputView = null;
         mAssistManager.onLockscreenShown();
     }
 
@@ -3669,6 +3699,7 @@
     public boolean hideKeyguard() {
         boolean staying = mLeaveOpenOnKeyguardHide;
         setBarState(StatusBarState.SHADE);
+        View viewToClick = null;
         if (mLeaveOpenOnKeyguardHide) {
             mLeaveOpenOnKeyguardHide = false;
             long delay = calculateGoingToFullShadeDelay();
@@ -3677,6 +3708,8 @@
                 mDraggedDownRow.setUserLocked(false);
                 mDraggedDownRow = null;
             }
+            viewToClick = mPendingRemoteInputView;
+            mPendingRemoteInputView = null;
 
             // Disable layout transitions in navbar for this transition because the load is just
             // too heavy for the CPU and GPU on any device.
@@ -3694,6 +3727,10 @@
         }
         updateKeyguardState(staying, false /* fromShadeLocked */);
 
+        if (viewToClick != null) {
+            viewToClick.callOnClick();
+        }
+
         // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
         // visibilities so next time we open the panel we know the correct height already.
         if (mQSPanel != null) {
@@ -4057,6 +4094,7 @@
             mLeaveOpenOnKeyguardHide = true;
             showBouncer();
             mDraggedDownRow = row;
+            mPendingRemoteInputView = null;
         } else {
             mNotificationPanel.animateToFullShade(0 /* delay */);
             setBarState(StatusBarState.SHADE_LOCKED);
@@ -4065,6 +4103,13 @@
     }
 
     @Override
+    protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
+        mLeaveOpenOnKeyguardHide = true;
+        showBouncer();
+        mPendingRemoteInputView = clicked;
+    }
+
+    @Override
     public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
         mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
         if (mState == StatusBarState.KEYGUARD && nowExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index da2c20d..2af2009 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -147,8 +147,9 @@
 
         mServices = new TileServices(this, mLooper);
 
-        mAutoTiles = new AutoTileManager(context, this);
         TunerService.get(mContext).addTunable(this, TILES_SETTING);
+        // AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
+        mAutoTiles = new AutoTileManager(context, this);
     }
 
     public void setHeaderView(View view) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index fe46385..3bb141a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -20,18 +20,18 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.content.res.Configuration;
 import android.graphics.Rect;
-import android.graphics.drawable.Animatable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
-import android.widget.Switch;
 import android.widget.TextView;
 import android.widget.Toast;
 import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
@@ -49,33 +49,32 @@
     private NextAlarmController mNextAlarmController;
     private SettingsButton mSettingsButton;
     private View mSettingsContainer;
-    private TextView mAlarmStatus;
-    private View mQsDetailHeader;
 
-    private ImageView mQsDetailHeaderProgress;
+    private TextView mAlarmStatus;
+    private TextView mAlarmStatusCollapsed;
+
     private QSPanel mQsPanel;
-    private Switch mQsDetailHeaderSwitch;
 
     private boolean mExpanded;
     private boolean mAlarmShowing;
-    private boolean mShowingDetail;
 
-    private boolean mDetailTransitioning;
     private ViewGroup mExpandedGroup;
     private ViewGroup mDateTimeGroup;
-    private View mEmergencyOnly;
-    private TextView mQsDetailHeaderTitle;
+    private ViewGroup mDateTimeAlarmGroup;
+    private TextView mEmergencyOnly;
+
     private boolean mListening;
     private AlarmManager.AlarmClockInfo mNextAlarm;
 
     private QuickQSPanel mHeaderQsPanel;
     private boolean mShowEmergencyCallsOnly;
-    private float mDateTimeTranslation;
     private MultiUserSwitch mMultiUserSwitch;
     private ImageView mMultiUserAvatar;
-    private View mQsDetailHeaderBack;
 
-    private final int[] mTmpInt2 = new int[2];
+    private float mDateTimeTranslation;
+    private float mDateTimeAlarmTranslation;
+    private float mExpansionFraction;
+    private float mDateScaleFactor;
 
     public QuickStatusBarHeader(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -85,11 +84,12 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mEmergencyOnly = findViewById(R.id.header_emergency_calls_only);
-        mDateTimeTranslation = mContext.getResources().getDimension(
-                R.dimen.qs_date_anim_translation);
+        mEmergencyOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
+
+        mDateTimeAlarmGroup = (ViewGroup) findViewById(R.id.date_time_alarm_group);
+        mDateTimeAlarmGroup.findViewById(R.id.empty_time_view).setVisibility(View.GONE);
         mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group);
-        mDateTimeGroup.findViewById(R.id.empty_time_view).setVisibility(View.GONE);
+
         mExpandedGroup = (ViewGroup) findViewById(R.id.expanded_group);
 
         mHeaderQsPanel = (QuickQSPanel) findViewById(R.id.quick_qs_panel);
@@ -98,16 +98,10 @@
         mSettingsContainer = findViewById(R.id.settings_button_container);
         mSettingsButton.setOnClickListener(this);
 
+        mAlarmStatusCollapsed = (TextView) findViewById(R.id.alarm_status_collapsed);
         mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
         mAlarmStatus.setOnClickListener(this);
 
-        mQsDetailHeader = findViewById(R.id.qs_detail_header);
-        mQsDetailHeader.setAlpha(0);
-        mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
-        mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
-        mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
-        mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
-
         mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
         mMultiUserAvatar = (ImageView) mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
 
@@ -124,6 +118,29 @@
                         getHeight()));
             }
         });
+        updateResources();
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateResources();
+    }
+
+    private void updateResources() {
+        FontSizeUtils.updateFontSize(mAlarmStatus, R.dimen.qs_date_collapsed_size);
+        FontSizeUtils.updateFontSize(mEmergencyOnly, R.dimen.qs_emergency_calls_only_text_size);
+
+        mDateTimeTranslation = mContext.getResources().getDimension(
+                R.dimen.qs_date_anim_translation);
+        mDateTimeAlarmTranslation = mContext.getResources().getDimension(
+                R.dimen.qs_date_alarm_anim_translation);
+        float dateCollapsedSize = mContext.getResources().getDimension(
+                R.dimen.qs_date_collapsed_text_size);
+        float dateExpandedSize = mContext.getResources().getDimension(
+                R.dimen.qs_date_text_size);
+        mDateScaleFactor = dateExpandedSize / dateCollapsedSize - 1;
+        updateDateTimePosition();
     }
 
     @Override
@@ -154,15 +171,41 @@
 
     @Override
     public void setExpansion(float headerExpansionFraction) {
+        mExpansionFraction = headerExpansionFraction;
+
         mExpandedGroup.setAlpha(headerExpansionFraction);
         mExpandedGroup.setVisibility(headerExpansionFraction > 0 ? View.VISIBLE : View.INVISIBLE);
+
         mHeaderQsPanel.setAlpha(1 - headerExpansionFraction);
         mHeaderQsPanel.setVisibility(headerExpansionFraction < 1 ? View.VISIBLE : View.INVISIBLE);
 
-        mDateTimeGroup.setTranslationY(headerExpansionFraction * mDateTimeTranslation);
+        mAlarmStatus.setAlpha(headerExpansionFraction);
+        mAlarmStatusCollapsed.setAlpha(1 - headerExpansionFraction);
+        updateAlarmVisibilities();
+
+        float textScale = headerExpansionFraction * mDateScaleFactor;
+        mDateTimeGroup.setScaleX(1 + textScale);
+        mDateTimeGroup.setScaleY(1 + textScale);
+        mDateTimeGroup.setTranslationX(textScale * mDateTimeGroup.getWidth() / 2);
+        mDateTimeGroup.setTranslationY(textScale * mDateTimeGroup.getHeight() / 2);
+        updateDateTimePosition();
+
         mEmergencyOnly.setAlpha(headerExpansionFraction);
     }
 
+    private void updateAlarmVisibilities() {
+        mAlarmStatus.setVisibility(mAlarmShowing && mExpansionFraction > 0
+                ? View.VISIBLE : View.INVISIBLE);
+        mAlarmStatusCollapsed.setVisibility(mAlarmShowing && mExpansionFraction < 1
+                ? View.VISIBLE : View.INVISIBLE);
+    }
+
+    private void updateDateTimePosition() {
+        float translation = mAlarmShowing ? mDateTimeAlarmTranslation
+                : mDateTimeTranslation;
+        mDateTimeAlarmGroup.setTranslationY(mExpansionFraction * translation);
+    }
+
     public void setListening(boolean listening) {
         if (listening == mListening) {
             return;
@@ -174,12 +217,12 @@
 
     @Override
     public void updateEverything() {
+        updateDateTimePosition();
         updateVisibilities();
     }
 
     private void updateVisibilities() {
-        mAlarmStatus.setVisibility(mAlarmShowing ? View.VISIBLE : View.GONE);
-        mQsDetailHeader.setVisibility(mExpanded && mShowingDetail ? View.VISIBLE : View.INVISIBLE);
+        updateAlarmVisibilities();
         mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
                 ? View.VISIBLE : View.INVISIBLE);
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
@@ -188,10 +231,6 @@
                 : View.GONE);
     }
 
-    private boolean hasMultiUsers() {
-        return false;
-    }
-
     private void updateListeners() {
         if (mListening) {
             mNextAlarmController.addStateChangedCallback(this);
@@ -210,7 +249,6 @@
         mQsPanel = qsPanel;
         setupHost(qsPanel.getHost());
         if (mQsPanel != null) {
-            mQsPanel.setCallback(mQsPanelCallback);
             mMultiUserSwitch.setQsPanel(qsPanel);
         }
     }
@@ -290,121 +328,4 @@
             }
         }
     }
-
-    private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
-        private boolean mScanState;
-
-        @Override
-        public void onShowingDetail(final QSTile.DetailAdapter detail) {
-            mDetailTransitioning = true;
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    handleShowingDetail(detail);
-                }
-            });
-        }
-
-        @Override
-        public void onToggleStateChanged(final boolean state) {
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    handleToggleStateChanged(state);
-                }
-            });
-
-        }
-
-        @Override
-        public void onScanStateChanged(final boolean state) {
-            post(new Runnable() {
-                @Override
-                public void run() {
-                    handleScanStateChanged(state);
-                }
-            });
-        }
-
-        private void handleToggleStateChanged(boolean state) {
-            mQsDetailHeaderSwitch.setChecked(state);
-        }
-
-        private void handleScanStateChanged(boolean state) {
-            if (mScanState == state) return;
-            mScanState = state;
-            final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
-            if (state) {
-                mQsDetailHeaderProgress.animate().alpha(1f);
-                anim.start();
-            } else {
-                mQsDetailHeaderProgress.animate().alpha(0f);
-                anim.stop();
-            }
-        }
-
-        private void handleShowingDetail(final QSTile.DetailAdapter detail) {
-            final boolean showingDetail = detail != null;
-            transition(mDateTimeGroup, !showingDetail);
-            transition(mExpandedGroup, !showingDetail);
-            if (mAlarmShowing) {
-                transition(mAlarmStatus, !showingDetail);
-            }
-            transition(mQsDetailHeader, showingDetail);
-            mShowingDetail = showingDetail;
-            if (showingDetail) {
-                mQsDetailHeaderTitle.setText(detail.getTitle());
-                final Boolean toggleState = detail.getToggleState();
-                if (toggleState == null) {
-                    mQsDetailHeaderSwitch.setVisibility(INVISIBLE);
-                    mQsDetailHeader.setClickable(false);
-                } else {
-                    mQsDetailHeaderSwitch.setVisibility(VISIBLE);
-                    mQsDetailHeaderSwitch.setChecked(toggleState);
-                    mQsDetailHeader.setClickable(true);
-                    mQsDetailHeader.setOnClickListener(new OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            boolean checked = !mQsDetailHeaderSwitch.isChecked();
-                            mQsDetailHeaderSwitch.setChecked(checked);
-                            detail.setToggleState(checked);
-                        }
-                    });
-                }
-                mQsDetailHeaderBack.setOnClickListener(new OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        v.getLocationInWindow(mTmpInt2);
-                        mTmpInt2[0] += v.getWidth() / 2;
-                        mTmpInt2[1] += v.getHeight() / 2;
-                        mQsPanel.showDetailAdapter(false, null, mTmpInt2);
-                    }
-                });
-            } else {
-                mQsDetailHeader.setClickable(false);
-            }
-        }
-
-        private void transition(final View v, final boolean in) {
-            if (in) {
-                v.bringToFront();
-                v.setVisibility(VISIBLE);
-            }
-            if (v.hasOverlappingRendering()) {
-                v.animate().withLayer();
-            }
-            v.animate()
-                    .alpha(in ? 1 : 0)
-                    .withEndAction(new Runnable() {
-                        @Override
-                        public void run() {
-                            if (!in) {
-                                v.setVisibility(INVISIBLE);
-                            }
-                            mDetailTransitioning = false;
-                        }
-                    })
-                    .start();
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index da16954..3682aa1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -16,31 +16,79 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import java.util.ArrayList;
+
 /**
  * Automatically reverses the order of children as they are added.
  * Also reverse the width and height values of layout params
  */
 public class ReverseLinearLayout extends LinearLayout {
 
+    private boolean mIsLayoutRtl;
+
     public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
 
     @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mIsLayoutRtl = getResources().getConfiguration()
+                .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+    }
+
+    @Override
     public void addView(View child) {
         reversParams(child.getLayoutParams());
-        super.addView(child, 0);
+        if (mIsLayoutRtl) {
+            super.addView(child);
+        } else {
+            super.addView(child, 0);
+        }
     }
 
     @Override
     public void addView(View child, ViewGroup.LayoutParams params) {
         reversParams(params);
-        super.addView(child, 0, params);
+        if (mIsLayoutRtl) {
+            super.addView(child, params);
+        } else {
+            super.addView(child, 0, params);
+        }
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateRTLOrder();
+    }
+
+    /**
+     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
+     * have to do it manually
+     */
+    private void updateRTLOrder() {
+        boolean isLayoutRtl = getResources().getConfiguration()
+                .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        if (mIsLayoutRtl != isLayoutRtl) {
+            // RTL changed, swap the order of all views.
+            int childCount = getChildCount();
+            ArrayList<View> childList = new ArrayList<>(childCount);
+            for (int i = 0; i < childCount; i++) {
+                childList.add(getChildAt(i));
+            }
+            removeAllViews();
+            for (int i = childCount - 1; i >= 0; i--) {
+                super.addView(childList.get(i));
+            }
+            mIsLayoutRtl = isLayoutRtl;
+        }
     }
 
     private void reversParams(ViewGroup.LayoutParams params) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index d2f1ca9..3e3b169 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -46,6 +46,7 @@
 import com.android.systemui.R;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTile;
+import com.android.systemui.qs.QSTile.DetailAdapter;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
 import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -742,7 +743,7 @@
         }
 
         @Override
-        public void onShowingDetail(final QSTile.DetailAdapter detail) {
+        public void onShowingDetail(final DetailAdapter detail, int x, int y) {
             mDetailTransitioning = true;
             post(new Runnable() {
                 @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 45aae2d..f61f31e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -22,6 +22,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.Handler;
@@ -58,8 +59,8 @@
 public class StatusBarIconController extends StatusBarIconList implements Tunable {
 
     public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
-
     public static final String ICON_BLACKLIST = "icon_blacklist";
+    public static final int DEFAULT_ICON_TINT = Color.WHITE;
 
     private Context mContext;
     private PhoneStatusBar mPhoneStatusBar;
@@ -79,8 +80,11 @@
     private int mIconSize;
     private int mIconHPadding;
 
-    private int mIconTint = Color.WHITE;
+    private int mIconTint = DEFAULT_ICON_TINT;
     private float mDarkIntensity;
+    private final Rect mTintArea = new Rect();
+    private static final Rect sTmpRect = new Rect();
+    private static final int[] sTmpInt2 = new int[2];
 
     private boolean mTransitionPending;
     private boolean mTintChangePending;
@@ -395,6 +399,25 @@
         }
     }
 
+    /**
+     * Sets the dark area so {@link #setIconsDark} only affects the icons in the specified area.
+     *
+     * @param darkArea the area in which icons should change it's tint, in logical screen
+     *                 coordinates
+     */
+    public void setIconsDarkArea(Rect darkArea) {
+        if (darkArea == null && mTintArea.isEmpty()) {
+            return;
+        }
+        if (darkArea == null) {
+            mTintArea.setEmpty();
+        } else {
+            mTintArea.set(darkArea);
+        }
+        applyIconTint();
+        mNotificationIconAreaController.setTintArea(darkArea);
+    }
+
     public void setIconsDark(boolean dark, boolean animate) {
         if (!animate) {
             setIconTintInternal(dark ? 1.0f : 0.0f);
@@ -446,14 +469,60 @@
         mPendingDarkIntensity = darkIntensity;
     }
 
+    /**
+     * @return the tint to apply to {@param view} depending on the desired tint {@param color} and
+     *         the screen {@param tintArea} in which to apply that tint
+     */
+    public static int getTint(Rect tintArea, View view, int color) {
+        if (isInArea(tintArea, view)) {
+            return color;
+        } else {
+            return DEFAULT_ICON_TINT;
+        }
+    }
+
+    /**
+     * @return the dark intensity to apply to {@param view} depending on the desired dark
+     *         {@param intensity} and the screen {@param tintArea} in which to apply that intensity
+     */
+    public static float getDarkIntensity(Rect tintArea, View view, float intensity) {
+        if (isInArea(tintArea, view)) {
+            return intensity;
+        } else {
+            return 0f;
+        }
+    }
+
+    /**
+     * @return true if more than half of the {@param view} area are in {@param area}, false
+     *         otherwise
+     */
+    private static boolean isInArea(Rect area, View view) {
+        if (area.isEmpty()) {
+            return true;
+        }
+        sTmpRect.set(area);
+        view.getLocationOnScreen(sTmpInt2);
+        int left = sTmpInt2[0];
+
+        int intersectStart = Math.max(left, area.left);
+        int intersectEnd = Math.min(left + view.getWidth(), area.right);
+        int intersectAmount = Math.max(0, intersectEnd - intersectStart);
+
+        boolean coversFullStatusBar = area.top <= 0;
+        boolean majorityOfWidth = 2 * intersectAmount > view.getWidth();
+        return majorityOfWidth && coversFullStatusBar;
+    }
+
     private void applyIconTint() {
         for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
             StatusBarIconView v = (StatusBarIconView) mStatusIcons.getChildAt(i);
-            v.setImageTintList(ColorStateList.valueOf(mIconTint));
+            v.setImageTintList(ColorStateList.valueOf(getTint(mTintArea, v, mIconTint)));
         }
-        mSignalCluster.setIconTint(mIconTint, mDarkIntensity);
-        mBatteryMeterView.setDarkIntensity(mDarkIntensity);
-        mClock.setTextColor(mIconTint);
+        mSignalCluster.setIconTint(mIconTint, mDarkIntensity, mTintArea);
+        mBatteryMeterView.setDarkIntensity(
+                isInArea(mTintArea, mBatteryMeterView) ? mDarkIntensity : 0);
+        mClock.setTextColor(getTint(mTintArea, mClock, mIconTint));
     }
 
     public void appTransitionPending() {
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 f065522..ab81712 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -39,10 +39,10 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Stack;
-import java.util.TreeSet;
 
 /**
  * A manager which handles heads up notifications which is a special mode where
@@ -90,7 +90,6 @@
     private int mSnoozeLengthMs;
     private ContentObserver mSettingsObserver;
     private HashMap<String, HeadsUpEntry> mHeadsUpEntries = new HashMap<>();
-    private TreeSet<HeadsUpEntry> mSortedEntries = new TreeSet<>();
     private HashSet<String> mSwipedOutKeys = new HashSet<>();
     private int mUser;
     private Clock mClock;
@@ -230,7 +229,6 @@
 
     private void removeHeadsUpEntry(NotificationData.Entry entry) {
         HeadsUpEntry remove = mHeadsUpEntries.remove(entry.key);
-        mSortedEntries.remove(remove);
         entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
         entry.row.setHeadsUp(false);
         setEntryPinned(remove, false /* isPinned */);
@@ -345,12 +343,21 @@
         return mHeadsUpEntries.get(key).entry;
     }
 
-    public TreeSet<HeadsUpEntry> getSortedEntries() {
-        return mSortedEntries;
+    public Collection<HeadsUpEntry> getAllEntries() {
+        return mHeadsUpEntries.values();
     }
 
     public HeadsUpEntry getTopEntry() {
-        return mSortedEntries.isEmpty() ? null : mSortedEntries.first();
+        if (mHeadsUpEntries.isEmpty()) {
+            return null;
+        }
+        HeadsUpEntry topEntry = null;
+        for (HeadsUpEntry entry: mHeadsUpEntries.values()) {
+            if (topEntry == null || entry.compareTo(topEntry) == -1) {
+                topEntry = entry;
+            }
+        }
+        return topEntry;
     }
 
     /**
@@ -374,26 +381,18 @@
             return;
         }
         if (mHasPinnedNotification) {
-            int minX = 0;
-            int maxX = 0;
-            int maxY = 0;
-            for (HeadsUpEntry entry : mSortedEntries) {
-                ExpandableNotificationRow row = entry.entry.row;
-                if (row.isPinned()) {
-                    if (row.isChildInGroup()) {
-                        final ExpandableNotificationRow groupSummary
-                                = mGroupManager.getGroupSummary(row.getStatusBarNotification());
-                        if (groupSummary != null) {
-                            row = groupSummary;
-                        }
-                    }
-                    row.getLocationOnScreen(mTmpTwoArray);
-                    minX = mTmpTwoArray[0];
-                    maxX = mTmpTwoArray[0] + row.getWidth();
-                    maxY = row.getIntrinsicHeight();
-                    break;
+            ExpandableNotificationRow topEntry = getTopEntry().entry.row;
+            if (topEntry.isChildInGroup()) {
+                final ExpandableNotificationRow groupSummary
+                        = mGroupManager.getGroupSummary(topEntry.getStatusBarNotification());
+                if (groupSummary != null) {
+                    topEntry = groupSummary;
                 }
             }
+            topEntry.getLocationOnScreen(mTmpTwoArray);
+            int minX = mTmpTwoArray[0];
+            int maxX = mTmpTwoArray[0] + topEntry.getWidth();
+            int maxY = topEntry.getIntrinsicHeight();
 
             info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
             info.touchableRegion.set(minX, 0, maxX, maxY);
@@ -413,7 +412,7 @@
         pw.print("  mSnoozeLengthMs="); pw.println(mSnoozeLengthMs);
         pw.print("  now="); pw.println(SystemClock.elapsedRealtime());
         pw.print("  mUser="); pw.println(mUser);
-        for (HeadsUpEntry entry: mSortedEntries) {
+        for (HeadsUpEntry entry: mHeadsUpEntries.values()) {
             pw.print("  HeadsUpEntry="); pw.println(entry.entry);
         }
         int N = mSnoozedPackages.size();
@@ -633,7 +632,6 @@
         }
 
         public void updateEntry(boolean updatePostTime) {
-            mSortedEntries.remove(HeadsUpEntry.this);
             long currentTime = mClock.currentTimeMillis();
             earliestRemovaltime = currentTime + mMinimumDisplayTime;
             if (updatePostTime) {
@@ -648,7 +646,6 @@
                 long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
                 mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
             }
-            mSortedEntries.add(HeadsUpEntry.this);
         }
 
         private boolean isSticky() {
@@ -658,6 +655,13 @@
 
         @Override
         public int compareTo(HeadsUpEntry o) {
+            boolean isPinned = entry.row.isPinned();
+            boolean otherPinned = o.entry.row.isPinned();
+            if (isPinned && !otherPinned) {
+                return -1;
+            } else if (!isPinned && otherPinned) {
+                return 1;
+            }
             boolean selfFullscreen = hasFullScreenIntent(entry);
             boolean otherFullscreen = hasFullScreenIntent(o.entry);
             if (selfFullscreen && !otherFullscreen) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 5cfcd89..49aec42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -43,16 +43,16 @@
     private static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5;
     private static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8;
 
-    private final int mChildPadding;
-    private final int mDividerHeight;
-    private final int mMaxNotificationHeight;
     private final List<View> mDividers = new ArrayList<>();
     private final List<ExpandableNotificationRow> mChildren = new ArrayList<>();
-    private final int mNotificationHeaderHeight;
-    private final int mNotificationAppearDistance;
-    private final int mNotificatonTopPadding;
     private final HybridNotificationViewManager mHybridViewManager;
-    private final float mCollapsedBottompadding;
+    private int mChildPadding;
+    private int mDividerHeight;
+    private int mMaxNotificationHeight;
+    private int mNotificationHeaderHeight;
+    private int mNotificationAppearDistance;
+    private int mNotificatonTopPadding;
+    private float mCollapsedBottompadding;
     private ViewInvertHelper mOverflowInvertHelper;
     private boolean mChildrenExpanded;
     private ExpandableNotificationRow mNotificationParent;
@@ -76,6 +76,11 @@
     public NotificationChildrenContainer(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        initDimens();
+        mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
+    }
+
+    private void initDimens() {
         mChildPadding = getResources().getDimensionPixelSize(
                 R.dimen.notification_children_padding);
         mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
@@ -89,7 +94,6 @@
         mNotificatonTopPadding = getResources().getDimensionPixelSize(
                 R.dimen.notification_children_container_top_padding);
         mCollapsedBottompadding = 11.5f * getResources().getDisplayMetrics().density;
-        mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
     }
 
     @Override
@@ -461,4 +465,16 @@
             mOverflowInvertHelper.setInverted(dark, fade, delay);
         }
     }
+
+    public void reInflateViews() {
+        initDimens();
+        for (int i = 0; i < mDividers.size(); i++) {
+            View prevDivider = mDividers.get(i);
+            int index = indexOfChild(prevDivider);
+            removeView(prevDivider);
+            View divider = inflateDivider();
+            addView(divider, index);
+            mDividers.set(i, divider);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index cc0e67d..bf4245b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -75,7 +75,7 @@
         ExpandableView.OnHeightChangedListener, NotificationGroupManager.OnGroupChangeListener {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
-    private static final String TAG = "NotificationStackScrollLayout";
+    private static final String TAG = "StackScroller";
     private static final boolean DEBUG = false;
     private static final float RUBBER_BAND_FACTOR_NORMAL = 0.35f;
     private static final float RUBBER_BAND_FACTOR_AFTER_EXPAND = 0.15f;
@@ -136,7 +136,7 @@
     private StackScrollState mCurrentStackScrollState = new StackScrollState(this);
     private AmbientState mAmbientState = new AmbientState();
     private NotificationGroupManager mGroupManager;
-    private ArrayList<View> mChildrenToAddAnimated = new ArrayList<>();
+    private HashSet<View> mChildrenToAddAnimated = new HashSet<>();
     private ArrayList<View> mAddedHeadsUpChildren = new ArrayList<>();
     private ArrayList<View> mChildrenToRemoveAnimated = new ArrayList<>();
     private ArrayList<View> mSnappedBackChildren = new ArrayList<>();
@@ -213,7 +213,6 @@
      * animating.
      */
     private boolean mOnlyScrollingInThisMotion;
-    private ViewGroup mScrollView;
     private boolean mInterceptDelegateEnabled;
     private boolean mDelegateToScrollView;
     private boolean mDisallowScrollingInThisMotion;
@@ -281,6 +280,7 @@
             setDimAmount((Float) animation.getAnimatedValue());
         }
     };
+    private ViewGroup mQsContainer;
 
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -474,6 +474,7 @@
      * modifications to {@link #mOwnScrollY} are performed to reflect it in the view layout.
      */
     private void updateChildren() {
+        updateScrollStateForAddedChildren();
         mAmbientState.setScrollY(mOwnScrollY);
         mStackScrollAlgorithm.getStackScrollState(mAmbientState, mCurrentStackScrollState);
         if (!isCurrentlyAnimating() && !mNeedsAnimation) {
@@ -483,6 +484,28 @@
         }
     }
 
+    private void updateScrollStateForAddedChildren() {
+        if (mChildrenToAddAnimated.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < getChildCount(); i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (mChildrenToAddAnimated.contains(child)) {
+                int startingPosition = getPositionInLinearLayout(child);
+                int padding = child.needsIncreasedPadding()
+                        ? mIncreasedPaddingBetweenElements :
+                        mPaddingBetweenElements;
+                int childHeight = getIntrinsicHeight(child) + padding;
+                if (startingPosition < mOwnScrollY) {
+                    // This child starts off screen, so let's keep it offscreen to keep the others visible
+
+                    mOwnScrollY += childHeight;
+                }
+            }
+        }
+        clampScrollPosition();
+    }
+
     private void requestChildrenUpdate() {
         if (!mChildrenUpdateRequested) {
             getViewTreeObserver().addOnPreDrawListener(mChildrenUpdater);
@@ -607,12 +630,8 @@
         mLongPressListener = listener;
     }
 
-    public void setScrollView(ViewGroup scrollView) {
-        mScrollView = scrollView;
-    }
-
-    public void setInterceptDelegateEnabled(boolean interceptDelegateEnabled) {
-        mInterceptDelegateEnabled = interceptDelegateEnabled;
+    public void setQsContainer(ViewGroup qsContainer) {
+        mQsContainer = qsContainer;
     }
 
     public void onChildDismissed(View v) {
@@ -860,13 +879,6 @@
     public boolean onTouchEvent(MotionEvent ev) {
         boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
                 || ev.getActionMasked()== MotionEvent.ACTION_UP;
-        if (mDelegateToScrollView) {
-            if (isCancelOrUp) {
-                mDelegateToScrollView = false;
-            }
-            transformTouchEvent(ev, this, mScrollView);
-            return mScrollView.onTouchEvent(ev);
-        }
         handleEmptySpaceClick(ev);
         boolean expandWantsIt = false;
         if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion) {
@@ -906,6 +918,9 @@
         if (!isScrollingEnabled()) {
             return false;
         }
+        if (ev.getY() < mQsContainer.getBottom()) {
+            return false;
+        }
         initVelocityTrackerIfNotExists();
         mVelocityTracker.addMovement(ev);
 
@@ -1648,12 +1663,17 @@
                 bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight());
                 bottom = Math.min(bottom, getHeight());
             }
-        } else if (mPhoneStatusBar.getBarState() == StatusBarState.KEYGUARD) {
-            top = mTopPadding;
+        } else {
+            top = (int) (mTopPadding + mStackTranslation);
             bottom = top;
         }
-        mBackgroundBounds.top = Math.max(0, top);
-        mBackgroundBounds.bottom = Math.min(getHeight(), bottom);
+        if (mPhoneStatusBar.getBarState() != StatusBarState.KEYGUARD) {
+            mBackgroundBounds.top = (int) Math.max(mTopPadding + mStackTranslation, top);
+        } else {
+            // otherwise the animation from the shade to the keyguard will jump as it's maxed
+            mBackgroundBounds.top = Math.max(0, top);
+        }
+        mBackgroundBounds.bottom = Math.min(getHeight(), Math.max(bottom, top));
     }
 
     private ActivatableNotificationView getFirstPinnedHeadsUp() {
@@ -1748,15 +1768,13 @@
      * account.
      *
      * @param qsHeight the top padding imposed by the quick settings panel
-     * @param scrollY how much the notifications are scrolled inside the QS/notifications scroll
-     *                container
      * @param animate whether to animate the change
      * @param ignoreIntrinsicPadding if true, {@link #getIntrinsicPadding()} is ignored and
      *                               {@code qsHeight} is the final top padding
      */
-    public void updateTopPadding(float qsHeight, int scrollY, boolean animate,
+    public void updateTopPadding(float qsHeight, boolean animate,
             boolean ignoreIntrinsicPadding) {
-        float start = qsHeight - scrollY;
+        float start = qsHeight;
         float stackHeight = getHeight() - start;
         int minStackHeight = getMinStackHeight();
         if (stackHeight <= minStackHeight) {
@@ -1839,15 +1857,6 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (mInterceptDelegateEnabled) {
-            transformTouchEvent(ev, this, mScrollView);
-            if (mScrollView.onInterceptTouchEvent(ev)) {
-                mDelegateToScrollView = true;
-                removeLongPressCallback();
-                return true;
-            }
-            transformTouchEvent(ev, mScrollView, this);
-        }
         initDownStates(ev);
         handleEmptySpaceClick(ev);
         boolean expandWantsIt = false;
@@ -2129,7 +2138,7 @@
     }
 
     private void updateAnimationState(View child) {
-        updateAnimationState((mAnimationsEnabled || isPinnedHeadsUp(child)) && mIsExpanded, child);
+        updateAnimationState(mAnimationsEnabled && (mIsExpanded || isPinnedHeadsUp(child)), child);
     }
 
 
@@ -2865,13 +2874,23 @@
     }
 
     public void setDismissView(DismissView dismissView) {
+        int index = -1;
+        if (mDismissView != null) {
+            index = indexOfChild(mDismissView);
+            removeView(mDismissView);
+        }
         mDismissView = dismissView;
-        addView(mDismissView);
+        addView(mDismissView, index);
     }
 
     public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
+        int index = -1;
+        if (mEmptyShadeView != null) {
+            index = indexOfChild(mEmptyShadeView);
+            removeView(mEmptyShadeView);
+        }
         mEmptyShadeView = emptyShadeView;
-        addView(mEmptyShadeView);
+        addView(mEmptyShadeView, index);
     }
 
     public void updateEmptyShadeView(boolean visible) {
@@ -3206,6 +3225,10 @@
         }
     }
 
+    public boolean isExpanded() {
+        return mIsExpanded;
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index f6959f0..e87b363 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -39,17 +39,14 @@
     private static final String LOG_TAG = "StackScrollAlgorithm";
 
     private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3;
-    private static final int MAX_ITEMS_IN_TOP_STACK = 3;
 
     private int mPaddingBetweenElements;
     private int mIncreasedPaddingBetweenElements;
     private int mCollapsedSize;
-    private int mTopStackPeekSize;
     private int mBottomStackPeekSize;
     private int mZDistanceBetweenElements;
     private int mZBasicHeight;
 
-    private StackIndentationFunctor mTopStackIndentationFunctor;
     private StackIndentationFunctor mBottomStackIndentationFunctor;
 
     private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
@@ -58,12 +55,8 @@
     private boolean mIsExpanded;
     private ExpandableView mFirstChildWhileExpanding;
     private boolean mExpandedOnStart;
-    private int mTopStackTotalSize;
     private int mBottomStackSlowDownLength;
-    private int mTopStackSlowDownLength;
     private int mCollapseSecondCardPadding;
-    private ExpandableView mFirstChild;
-    private int mFirstChildMinHeight;
 
     public StackScrollAlgorithm(Context context) {
         initView(context);
@@ -71,22 +64,6 @@
 
     public void initView(Context context) {
         initConstants(context);
-        updatePadding();
-    }
-
-    private void updatePadding() {
-        mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements
-                + mTopStackPeekSize;
-        mTopStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
-                MAX_ITEMS_IN_TOP_STACK,
-                mTopStackPeekSize,
-                mTopStackTotalSize - mTopStackPeekSize,
-                0.5f);
-        mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
-                MAX_ITEMS_IN_BOTTOM_STACK,
-                mBottomStackPeekSize,
-                getBottomStackSlowDownLength(),
-                0.5f);
     }
 
     public int getBottomStackSlowDownLength() {
@@ -100,8 +77,6 @@
                 .getDimensionPixelSize(R.dimen.notification_divider_height_increased);
         mCollapsedSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.notification_min_height);
-        mTopStackPeekSize = context.getResources()
-                .getDimensionPixelSize(R.dimen.top_stack_peek_amount);
         mBottomStackPeekSize = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
         mZDistanceBetweenElements = Math.max(1, context.getResources()
@@ -109,10 +84,13 @@
         mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
         mBottomStackSlowDownLength = context.getResources()
                 .getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
-        mTopStackSlowDownLength = context.getResources()
-                .getDimensionPixelSize(R.dimen.top_stack_slow_down_length);
         mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
                 R.dimen.notification_collapse_second_card_padding);
+        mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
+                MAX_ITEMS_IN_BOTTOM_STACK,
+                mBottomStackPeekSize,
+                getBottomStackSlowDownLength(),
+                0.5f);
     }
 
     public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -123,32 +101,13 @@
         // First we reset the view states to their default values.
         resultState.resetViewStates();
 
-        algorithmState.itemsInTopStack = 0.0f;
-        algorithmState.partialInTop = 0.0f;
-        algorithmState.lastTopStackIndex = 0;
-        algorithmState.scrolledPixelsTop = 0;
-        algorithmState.itemsInBottomStack = 0.0f;
-        algorithmState.partialInBottom = 0.0f;
-        mFirstChildMinHeight = mFirstChild == null ? 0 : mFirstChild.getMinHeight();
-        float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */);
+        initAlgorithmState(resultState, algorithmState, ambientState);
 
-        int scrollY = ambientState.getScrollY();
-
-        // Due to the overScroller, the stackscroller can have negative scroll state. This is
-        // already accounted for by the top padding and doesn't need an additional adaption
-        scrollY = Math.max(0, scrollY);
-        algorithmState.scrollY = (int) (scrollY + mFirstChildMinHeight + bottomOverScroll);
-
-        initAlgorithmState(resultState, algorithmState);
-
-        // Phase 1:
-        findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState, ambientState);
-
-        // Phase 2:
         updatePositionsForState(resultState, algorithmState, ambientState);
 
-        // Phase 3:
-        updateZValuesForState(resultState, algorithmState);
+        updateZValuesForState(resultState, algorithmState, ambientState);
+
+        updateHeadsUpStates(resultState, algorithmState, ambientState);
 
         handleDraggedViews(ambientState, resultState, algorithmState);
         updateDimmedActivatedHideSensitive(ambientState, resultState, algorithmState);
@@ -185,6 +144,7 @@
     private void updateClipping(StackScrollState resultState,
             StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
         boolean dismissAllInProgress = ambientState.isDismissAllInProgress();
+        float drawStart = ambientState.getTopPadding() + ambientState.getStackTranslation();
         float previousNotificationEnd = 0;
         float previousNotificationStart = 0;
         boolean previousNotificationIsSwiped = false;
@@ -192,6 +152,10 @@
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
             StackViewState state = resultState.getViewStateForView(child);
+            if (!child.mustStayOnScreen()) {
+                previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
+                previousNotificationStart = Math.max(drawStart, previousNotificationStart);
+            }
             float newYTranslation = state.yTranslation;
             float newHeight = state.height;
             // apply clipping and shadow
@@ -222,7 +186,7 @@
                 } else {
                     previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
                     previousNotificationEnd = newNotificationEnd;
-                    previousNotificationStart = newYTranslation + state.clipTopAmount;
+                    previousNotificationStart =newYTranslation + state.clipTopAmount;
                 }
             }
         }
@@ -314,8 +278,20 @@
     /**
      * Initialize the algorithm state like updating the visible children.
      */
-    private void initAlgorithmState(StackScrollState resultState,
-            StackScrollAlgorithmState state) {
+    private void initAlgorithmState(StackScrollState resultState, StackScrollAlgorithmState state,
+            AmbientState ambientState) {
+        state.itemsInBottomStack = 0.0f;
+        state.partialInBottom = 0.0f;
+        float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */);
+
+        int scrollY = ambientState.getScrollY();
+
+        // Due to the overScroller, the stackscroller can have negative scroll state. This is
+        // already accounted for by the top padding and doesn't need an additional adaption
+        scrollY = Math.max(0, scrollY);
+        state.scrollY = (int) (scrollY + bottomOverScroll);
+
+        //now init the visible children and update paddings
         ViewGroup hostView = resultState.getHostView();
         int childCount = hostView.getChildCount();
         state.visibleChildren.clear();
@@ -383,15 +359,9 @@
         float bottomStackStart = bottomPeekStart - mBottomStackSlowDownLength;
 
         // The y coordinate of the current child.
-        float currentYPosition = 0.0f;
-
-        // How far in is the element currently transitioning into the bottom stack.
-        float yPositionInScrollView = 0.0f;
+        float currentYPosition = -algorithmState.scrollY;
 
         int childCount = algorithmState.visibleChildren.size();
-        int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f
-                ? algorithmState.lastTopStackIndex
-                : (int) algorithmState.itemsInTopStack;
         int paddingAfterChild;
         for (int i = 0; i < childCount; i++) {
             ExpandableView child = algorithmState.visibleChildren.get(i);
@@ -400,47 +370,16 @@
             paddingAfterChild = getPaddingAfterChild(algorithmState, child);
             int childHeight = getMaxAllowedChildHeight(child);
             int minHeight = child.getMinHeight();
-            float yPositionInScrollViewAfterElement = yPositionInScrollView
-                    + childHeight
-                    + paddingAfterChild;
-            float scrollOffset = yPositionInScrollView - algorithmState.scrollY +
-                    mFirstChildMinHeight;
-
-            if (i == algorithmState.lastTopStackIndex + 1) {
-                // Normally the position of this child is the position in the regular scrollview,
-                // but if the two stacks are very close to each other,
-                // then have have to push it even more upwards to the position of the bottom
-                // stack start.
-                currentYPosition = Math.min(scrollOffset, bottomStackStart);
-            }
             childViewState.yTranslation = currentYPosition;
+            if (i == 0) {
+                updateFirstChildHeight(child, childViewState, childHeight, ambientState);
+            }
 
             // The y position after this element
             float nextYPosition = currentYPosition + childHeight +
                     paddingAfterChild;
-
-            if (i <= algorithmState.lastTopStackIndex) {
+            if (nextYPosition >= bottomStackStart) {
                 // Case 1:
-                // We are in the top Stack
-                updateStateForTopStackChild(algorithmState, child,
-                        numberOfElementsCompletelyIn, i, childHeight, childViewState, scrollOffset);
-                clampPositionToTopStackEnd(childViewState, childHeight);
-
-                // check if we are overlapping with the bottom stack
-                if (childViewState.yTranslation + childHeight + paddingAfterChild
-                        >= bottomStackStart && !mIsExpansionChanging && i != 0) {
-                    // we just collapse this element slightly
-                    int newSize = (int) Math.max(bottomStackStart - paddingAfterChild -
-                            childViewState.yTranslation, minHeight);
-                    childViewState.height = newSize;
-                    updateStateForChildTransitioningInBottom(algorithmState, bottomStackStart,
-                            child, childViewState.yTranslation, childViewState,
-                            childHeight);
-                }
-                clampPositionToBottomStackStart(childViewState, childViewState.height,
-                        minHeight, ambientState);
-            } else if (nextYPosition >= bottomStackStart) {
-                // Case 2:
                 // We are in the bottom stack.
                 if (currentYPosition >= bottomStackStart) {
                     // According to the regular scroll view we are fully translated out of the
@@ -455,36 +394,30 @@
                             childViewState, childHeight);
                 }
             } else {
-                // Case 3:
+                // Case 2:
                 // We are in the regular scroll area.
                 childViewState.location = StackViewState.LOCATION_MAIN_AREA;
-                clampYTranslation(childViewState, childHeight, ambientState);
+                clampPositionToBottomStackStart(childViewState, childViewState.height, childHeight,
+                        ambientState);
             }
 
-            // The first card is always rendered.
-            if (i == 0) {
-                childViewState.hidden = false;
-                childViewState.shadowAlpha = 1.0f;
-                childViewState.yTranslation = Math.max(
-                        mFirstChildMinHeight - algorithmState.scrollY, 0);
-                if (childViewState.yTranslation + childViewState.height
-                        > bottomPeekStart - mCollapseSecondCardPadding) {
-                    childViewState.height = (int) Math.max(
-                            bottomPeekStart - mCollapseSecondCardPadding
-                                    - childViewState.yTranslation, mFirstChildMinHeight);
-                }
-                childViewState.location = StackViewState.LOCATION_FIRST_CARD;
+            if (i == 0 && ambientState.getScrollY() <= 0) {
+                // The first card can get into the bottom stack if it's the only one
+                // on the lockscreen which pushes it up. Let's make sure that doesn't happen and
+                // it stays at the top
+                childViewState.yTranslation = Math.max(0, childViewState.yTranslation);
+            }
+            currentYPosition = childViewState.yTranslation + childHeight + paddingAfterChild;
+            if (currentYPosition <= 0) {
+                childViewState.location = StackViewState.LOCATION_HIDDEN_TOP;
             }
             if (childViewState.location == StackViewState.LOCATION_UNKNOWN) {
                 Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
             }
-            currentYPosition = childViewState.yTranslation + childHeight + paddingAfterChild;
-            yPositionInScrollView = yPositionInScrollViewAfterElement;
 
             childViewState.yTranslation += ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
         }
-        updateHeadsUpStates(resultState, algorithmState, ambientState);
     }
 
     private int getPaddingAfterChild(StackScrollAlgorithmState algorithmState,
@@ -506,24 +439,27 @@
             ExpandableNotificationRow row = (ExpandableNotificationRow) child;
             if (!row.isHeadsUp()) {
                 break;
-            } else if (topHeadsUpEntry == null) {
-                topHeadsUpEntry = row;
             }
             StackViewState childState = resultState.getViewStateForView(row);
+            if (topHeadsUpEntry == null) {
+                topHeadsUpEntry = row;
+                childState.location = StackViewState.LOCATION_FIRST_HUN;
+            }
             boolean isTopEntry = topHeadsUpEntry == row;
+            float unmodifiedEndLocation = childState.yTranslation + childState.height;
             if (mIsExpanded) {
-                // Ensure that the heads up is always visible even when scrolled off from the bottom
-                float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height;
-                childState.yTranslation = Math.min(childState.yTranslation,
-                        bottomPosition);
+                // Ensure that the heads up is always visible even when scrolled off
+                clampHunToTop(ambientState, row, childState);
+                clampHunToMaxTranslation(ambientState, row, childState);
             }
             if (row.isPinned()) {
                 childState.yTranslation = Math.max(childState.yTranslation, 0);
                 childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
-                if (!isTopEntry) {
+                StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
+                if (!isTopEntry && (!mIsExpanded
+                        || unmodifiedEndLocation < topState.yTranslation + topState.height)) {
                     // Ensure that a headsUp doesn't vertically extend further than the heads-up at
                     // the top most z-position
-                    StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
                     childState.height = row.getIntrinsicHeight();
                     childState.yTranslation = topState.yTranslation + topState.height
                             - childState.height;
@@ -532,17 +468,23 @@
         }
     }
 
-    /**
-     * Clamp the yTranslation both up and down to valid positions.
-     *
-     * @param childViewState the view state of the child
-     * @param minHeight the minimum height of this child
-     */
-    private void clampYTranslation(StackViewState childViewState, int minHeight,
-            AmbientState ambientState) {
-        clampPositionToBottomStackStart(childViewState, childViewState.height, minHeight,
-                ambientState);
-        clampPositionToTopStackEnd(childViewState, childViewState.height);
+    private void clampHunToTop(AmbientState ambientState, ExpandableNotificationRow row,
+            StackViewState childState) {
+        float newTranslation = Math.max(ambientState.getTopPadding()
+                + ambientState.getStackTranslation(), childState.yTranslation);
+        childState.height = (int) Math.max(childState.height - (newTranslation
+                - childState.yTranslation), row.getMinHeight());
+        childState.yTranslation = newTranslation;
+    }
+
+    private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row,
+            StackViewState childState) {
+        float newTranslation;
+        float bottomPosition = ambientState.getMaxHeadsUpTranslation() - row.getMinHeight();
+        newTranslation = Math.min(childState.yTranslation, bottomPosition);
+        childState.height = (int) Math.max(childState.height
+                - (childState.yTranslation - newTranslation), row.getMinHeight());
+        childState.yTranslation = newTranslation;
     }
 
     /**
@@ -569,19 +511,6 @@
         }
     }
 
-    /**
-     * Clamp the yTranslation of the child up such that its end is at lest on the end of the top
-     * stack.
-     *
-     * @param childViewState the view state of the child
-     * @param childHeight the height of this child
-     */
-    private void clampPositionToTopStackEnd(StackViewState childViewState,
-            int childHeight) {
-        childViewState.yTranslation = Math.max(childViewState.yTranslation,
-                mFirstChildMinHeight - childHeight);
-    }
-
     private int getMaxAllowedChildHeight(View child) {
         if (child instanceof ExpandableView) {
             ExpandableView expandableView = (ExpandableView) child;
@@ -611,9 +540,6 @@
         }
         childViewState.yTranslation = transitioningPositionStart + offset - newHeight
                 - getPaddingAfterChild(algorithmState, child);
-
-        // We want at least to be at the end of the top stack when collapsing
-        clampPositionToTopStackEnd(childViewState, newHeight);
         childViewState.location = StackViewState.LOCATION_MAIN_AREA;
     }
 
@@ -642,177 +568,59 @@
         }
         childViewState.height = minHeight;
         childViewState.yTranslation = currentYPosition - minHeight;
-        clampPositionToTopStackEnd(childViewState, minHeight);
     }
 
-    private void updateStateForTopStackChild(StackScrollAlgorithmState algorithmState,
-            ExpandableView child, int numberOfElementsCompletelyIn, int i, int childHeight,
-            StackViewState childViewState, float scrollOffset) {
-
-
-        // First we calculate the index relative to the current stack window of size at most
-        // {@link #MAX_ITEMS_IN_TOP_STACK}
-        int paddedIndex = i - 1
-                - Math.max(numberOfElementsCompletelyIn - MAX_ITEMS_IN_TOP_STACK, 0);
-        if (paddedIndex >= 0) {
-
-            // We are currently visually entering the top stack
-            float distanceToStack = (childHeight + getPaddingAfterChild(algorithmState, child))
-                    - algorithmState.scrolledPixelsTop;
-            if (i == algorithmState.lastTopStackIndex
-                    && distanceToStack > (mTopStackTotalSize
-                    + getPaddingAfterChild(algorithmState, child))) {
-
-                // Child is currently translating into stack but not yet inside slow down zone.
-                // Handle it like the regular scrollview.
-                childViewState.yTranslation = scrollOffset;
-            } else {
-                // Apply stacking logic.
-                float numItemsBefore;
-                if (i == algorithmState.lastTopStackIndex) {
-                    numItemsBefore = 1.0f
-                            - (distanceToStack / (mTopStackTotalSize
-                            + getPaddingAfterChild(algorithmState, child)));
-                } else {
-                    numItemsBefore = algorithmState.itemsInTopStack - i;
-                }
-                // The end position of the current child
-                float currentChildEndY = mFirstChildMinHeight + mTopStackTotalSize
-                        - mTopStackIndentationFunctor.getValue(numItemsBefore);
-                childViewState.yTranslation = currentChildEndY - childHeight;
-            }
-            childViewState.location = StackViewState.LOCATION_TOP_STACK_PEEKING;
-        } else {
-            if (paddedIndex == -1) {
-                childViewState.shadowAlpha = 1.0f - algorithmState.partialInTop;
-            } else {
-                // We are hidden behind the top card and faded out, so we can hide ourselves.
-                childViewState.hidden = true;
-                childViewState.shadowAlpha = 0.0f;
-            }
-            childViewState.yTranslation = mFirstChildMinHeight - childHeight;
-            childViewState.location = StackViewState.LOCATION_TOP_STACK_HIDDEN;
-        }
-
-
-    }
 
     /**
-     * Find the number of items in the top stack and update the result state if needed.
+     * Update the height of the first child i.e clamp it to the bottom stack
      *
-     * @param resultState The result state to update if a height change of an child occurs
-     * @param algorithmState The state in which the current pass of the algorithm is currently in
+     *
+
+     * @param child the child to update
+     * @param childViewState the viewstate of the child
+     * @param childHeight the height of the child
+     * @param ambientState The ambient state of the algorithm
      */
-    private void findNumberOfItemsInTopStackAndUpdateState(StackScrollState resultState,
-            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
+    private void updateFirstChildHeight(ExpandableView child, StackViewState childViewState,
+            int childHeight, AmbientState ambientState) {
 
-        // The y Position if the element would be in a regular scrollView
-        float yPositionInScrollView = 0.0f;
-        int childCount = algorithmState.visibleChildren.size();
-        // find the number of elements in the top stack.
-        for (int i = 0; i < childCount; i++) {
-            ExpandableView child = algorithmState.visibleChildren.get(i);
-            StackViewState childViewState = resultState.getViewStateForView(child);
-            int childHeight = getMaxAllowedChildHeight(child);
-            int paddingAfterChild = getPaddingAfterChild(algorithmState, child);
-            float yPositionInScrollViewAfterElement = yPositionInScrollView
-                    + childHeight
-                    + paddingAfterChild;
-            if (yPositionInScrollView < algorithmState.scrollY) {
-                if (i == 0 && algorithmState.scrollY <= mFirstChildMinHeight) {
-
-                    // The starting position of the bottom stack peek
-                    int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
-                            mCollapseSecondCardPadding;
-                    // Collapse and expand the first child while the shade is being expanded
-                    float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
-                            ? mFirstChildMaxHeight
-                            : childHeight;
-                    childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
-                            mFirstChildMinHeight);
-                    algorithmState.itemsInTopStack = 1.0f;
-
-                } else if (yPositionInScrollViewAfterElement < algorithmState.scrollY) {
-                    // According to the regular scroll view we are fully off screen
-                    algorithmState.itemsInTopStack += 1.0f;
-                    if (i == 0) {
-                        childViewState.height = child.getMinHeight();
-                    }
-                } else {
-                    // According to the regular scroll view we are partially off screen
-
-                    // How much did we scroll into this child
-                    algorithmState.scrolledPixelsTop = algorithmState.scrollY
-                            - yPositionInScrollView;
-                    algorithmState.partialInTop = (algorithmState.scrolledPixelsTop) / (childHeight
-                            + paddingAfterChild);
-
-                    // Our element can be expanded, so this can get negative
-                    algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop);
-                    algorithmState.itemsInTopStack += algorithmState.partialInTop;
-
-                    if (i == 0) {
-                        // If it is expanded we have to collapse it to a new size
-                        float newSize = yPositionInScrollViewAfterElement
-                                - paddingAfterChild
-                                - algorithmState.scrollY + mFirstChildMinHeight;
-                        newSize = Math.max(mFirstChildMinHeight, newSize);
-                        algorithmState.itemsInTopStack = 1.0f;
-                        childViewState.height = (int) newSize;
-                    }
-                    algorithmState.lastTopStackIndex = i;
-                    break;
-                }
-            } else {
-                algorithmState.lastTopStackIndex = i - 1;
-                // We are already past the stack so we can end the loop
-                break;
-            }
-            yPositionInScrollView = yPositionInScrollViewAfterElement;
-        }
+            // The starting position of the bottom stack peek
+            int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
+                    mCollapseSecondCardPadding + ambientState.getScrollY();
+            // Collapse and expand the first child while the shade is being expanded
+            float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
+                    ? mFirstChildMaxHeight
+                    : childHeight;
+            childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
+                    child.getMinHeight());
     }
 
     /**
      * Calculate the Z positions for all children based on the number of items in both stacks and
      * save it in the resultState
-     *
-     * @param resultState The result state to update the zTranslation values
+     *  @param resultState The result state to update the zTranslation values
      * @param algorithmState The state in which the current pass of the algorithm is currently in
+     * @param ambientState The ambient state of the algorithm
      */
     private void updateZValuesForState(StackScrollState resultState,
-            StackScrollAlgorithmState algorithmState) {
+            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
         int childCount = algorithmState.visibleChildren.size();
-        for (int i = 0; i < childCount; i++) {
-            View child = algorithmState.visibleChildren.get(i);
+        int childrenOnTop = 0;
+        for (int i = childCount - 1; i >= 0; i--) {
+            ExpandableView child = algorithmState.visibleChildren.get(i);
             StackViewState childViewState = resultState.getViewStateForView(child);
-            if (i < algorithmState.itemsInTopStack) {
-                float stackIndex = algorithmState.itemsInTopStack - i;
-
-                // Ensure that the topmost item is a little bit higher than the rest when fully
-                // scrolled, to avoid drawing errors when swiping it out
-                float max = MAX_ITEMS_IN_TOP_STACK + (i == 0 ? 2.5f : 2);
-                stackIndex = Math.min(stackIndex, max);
-                if (i == 0 && algorithmState.itemsInTopStack < 2.0f) {
-
-                    // We only have the top item and an additional item in the top stack,
-                    // Interpolate the index from 0 to 2 while the second item is
-                    // translating in.
-                    stackIndex -= 1.0f;
-                    if (algorithmState.scrollY > mFirstChildMinHeight) {
-
-                        // Since there is a shadow treshhold, we cant just interpolate from 0 to
-                        // 2 but we interpolate from 0.1f to 2.0f when scrolled in. The jump in
-                        // height will not be noticable since we have padding in between.
-                        stackIndex = 0.1f + stackIndex * 1.9f;
-                    }
-                }
-                childViewState.zTranslation = mZBasicHeight
-                        + stackIndex * mZDistanceBetweenElements;
-            } else if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) {
+            if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) {
+                // We are in the bottom stack
                 float numItemsAbove = i - (childCount - 1 - algorithmState.itemsInBottomStack);
-                float translationZ = mZBasicHeight
+                childViewState.zTranslation = mZBasicHeight
                         - numItemsAbove * mZDistanceBetweenElements;
-                childViewState.zTranslation = translationZ;
+            } else if (child.mustStayOnScreen()
+                    && childViewState.yTranslation < ambientState.getTopPadding()
+                    + ambientState.getStackTranslation()) {
+                // TODO; do this more cleanly
+                childrenOnTop++;
+                childViewState.zTranslation = mZBasicHeight
+                        + childrenOnTop * mZDistanceBetweenElements;
             } else {
                 childViewState.zTranslation = mZBasicHeight;
             }
@@ -897,7 +705,6 @@
     }
 
     public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
-        mFirstChild = hostView.getFirstChildNotGone();
         if (mIsExpansionChanging) {
             hostView.post(new Runnable() {
                 @Override
@@ -922,26 +729,6 @@
         public int scrollY;
 
         /**
-         *  The quantity of items which are in the top stack.
-         */
-        public float itemsInTopStack;
-
-        /**
-         * how far in is the element currently transitioning into the top stack
-         */
-        public float partialInTop;
-
-        /**
-         * The number of pixels the last child in the top stack has scrolled in to the stack
-         */
-        public float scrolledPixelsTop;
-
-        /**
-         * The last item index which is in the top stack.
-         */
-        public int lastTopStackIndex;
-
-        /**
          * The quantity of items which are in the bottom stack.
          */
         public float itemsInBottomStack;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java
index 05fa27d..fa15195 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackViewState.java
@@ -24,12 +24,11 @@
     // These are flags such that we can create masks for filtering.
 
     public static final int LOCATION_UNKNOWN = 0x00;
-    public static final int LOCATION_FIRST_CARD = 0x01;
-    public static final int LOCATION_TOP_STACK_HIDDEN = 0x02;
-    public static final int LOCATION_TOP_STACK_PEEKING = 0x04;
-    public static final int LOCATION_MAIN_AREA = 0x08;
-    public static final int LOCATION_BOTTOM_STACK_PEEKING = 0x10;
-    public static final int LOCATION_BOTTOM_STACK_HIDDEN = 0x20;
+    public static final int LOCATION_FIRST_HUN = 0x01;
+    public static final int LOCATION_HIDDEN_TOP = 0x02;
+    public static final int LOCATION_MAIN_AREA = 0x04;
+    public static final int LOCATION_BOTTOM_STACK_PEEKING = 0x08;
+    public static final int LOCATION_BOTTOM_STACK_HIDDEN = 0x10;
     /** The view isn't layouted at all. */
     public static final int LOCATION_GONE = 0x40;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 784f610..110258c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.tv;
 
 import android.content.ComponentName;
+import android.graphics.Rect;
 import android.os.IBinder;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
@@ -68,7 +69,8 @@
     }
 
     @Override
-    public void setSystemUiVisibility(int vis, int mask) {
+    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
+            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
index 3e47d85..fac6338 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.os.Debug;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.util.Log;
@@ -53,13 +54,17 @@
 
     private static final int MAX_RUNNING_TASKS_COUNT = 10;
 
-    private static final int STATE_NO_PIP = 0;
-    private static final int STATE_PIP_OVERLAY = 1;
-    private static final int STATE_PIP_MENU = 2;
+    public static final int STATE_NO_PIP = 0;
+    public static final int STATE_PIP_OVERLAY = 1;
+    public static final int STATE_PIP_MENU = 2;
 
     private static final int TASK_ID_NO_PIP = -1;
     private static final int INVALID_RESOURCE_TYPE = -1;
 
+    public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1;
+    public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH = 0x2;
+    private int mSuspendPipResizingReason;
+
     private Context mContext;
     private IActivityManager mActivityManager;
     private int mState = STATE_NO_PIP;
@@ -87,7 +92,8 @@
             }
             if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
             mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
-            showPipOverlay(false);
+            // Set state to overlay so we show it when the pinned stack animation ends.
+            mState = STATE_PIP_OVERLAY;
             launchPipOnboardingActivityIfNeeded();
         }
     };
@@ -105,6 +111,23 @@
             movePipToFullscreen();
         }
     };
+    private final Runnable mOnPinnedStackAnimationEnded = new Runnable() {
+        @Override
+        public void run() {
+            if (mState == STATE_PIP_OVERLAY) {
+                showPipOverlay();
+            } else if (mState == STATE_PIP_MENU) {
+                showPipMenu();
+            }
+        }
+    };
+
+    private final Runnable mResizePinnedStackRunnable = new Runnable() {
+        @Override
+        public void run() {
+            resizePinnedStack(mState);
+        }
+    };
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -164,7 +187,7 @@
         if (!hasPipTasks()) {
             startPip();
         } else if (mState == STATE_PIP_OVERLAY) {
-            showPipMenu();
+            resizePinnedStack(STATE_PIP_MENU);
         }
     }
 
@@ -182,22 +205,10 @@
     public void closePip() {
         mState = STATE_NO_PIP;
         mPipTaskId = TASK_ID_NO_PIP;
-        StackInfo stackInfo = null;
         try {
-            stackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
-            if (stackInfo == null) {
-                return;
-            }
+            mActivityManager.removeStack(PINNED_STACK_ID);
         } catch (RemoteException e) {
-            Log.e(TAG, "getStackInfo failed", e);
-            return;
-        }
-        for (int taskId : stackInfo.taskIds) {
-            try {
-                mActivityManager.removeTask(taskId);
-            } catch (RemoteException e) {
-                Log.e(TAG, "removeTask failed", e);
-            }
+            Log.e(TAG, "removeStack failed", e);
         }
     }
 
@@ -210,11 +221,7 @@
         for (int i = mListeners.size() - 1; i >= 0; --i) {
             mListeners.get(i).onMoveToFullscreen();
         }
-        try {
-            mActivityManager.moveTasksToFullscreenStack(PINNED_STACK_ID, true);
-        } catch (RemoteException e) {
-            Log.e(TAG, "moveTasksToFullscreenStack failed", e);
-        }
+        resizePinnedStack(mState);
     }
 
     /**
@@ -222,25 +229,83 @@
      * stack to the default PIP bound {@link com.android.internal.R.string
      * .config_defaultPictureInPictureBounds}.
      */
-    public void showPipOverlay(boolean resizeStack) {
+    private void showPipOverlay() {
         if (DEBUG) Log.d(TAG, "showPipOverlay()");
         mState = STATE_PIP_OVERLAY;
         Intent intent = new Intent(mContext, PipOverlayActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchStackId(PINNED_STACK_ID);
-        if (resizeStack) {
-            options.setLaunchBounds(mPipBound);
-        }
         mContext.startActivity(intent, options.toBundle());
     }
 
     /**
+     * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called
+     * @param reason The reason for suspending resizing operations on the Pip.
+     */
+    public void suspendPipResizing(int reason) {
+        if (DEBUG) Log.d(TAG,
+                "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+        mSuspendPipResizingReason |= reason;
+    }
+
+    /**
+     * Resumes resizing operation on the Pip that was previously suspended.
+     * @param reason The reason resizing operations on the Pip was suspended.
+     */
+    public void resumePipResizing(int reason) {
+        if ((mSuspendPipResizingReason & reason) == 0) {
+            return;
+        }
+        if (DEBUG) Log.d(TAG,
+                "resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+        mSuspendPipResizingReason &= ~reason;
+        mHandler.post(mResizePinnedStackRunnable);
+    }
+
+    /**
+     * Resize the Pip to the appropriate size for the input state.
+     * @param state In Pip state also used to determine the new size for the Pip.
+     */
+    public void resizePinnedStack(int state) {
+        if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state);
+        mState = state;
+        Rect bounds;
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onPipResizeAboutToStart();
+        }
+        switch (mState) {
+            case STATE_PIP_MENU:
+                bounds = mMenuModePipBound;
+                break;
+            case STATE_NO_PIP:
+                bounds = null;
+                break;
+            default:
+                bounds = mPipBound;
+                break;
+        }
+
+        if (mSuspendPipResizingReason != 0) {
+            if (DEBUG) Log.d(TAG,
+                    "resizePinnedStack() deferring mSuspendPipResizingReason=" +
+                            mSuspendPipResizingReason);
+            return;
+        }
+
+        try {
+            mActivityManager.resizeStack(PINNED_STACK_ID, bounds, true, true, true);
+        } catch (RemoteException e) {
+            Log.e(TAG, "showPipMenu failed", e);
+        }
+    }
+
+    /**
      * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
      * stack to the centered PIP bound {@link com.android.internal.R.string
      * .config_centeredPictureInPictureBounds}.
      */
-    public void showPipMenu() {
+    private void showPipMenu() {
         if (DEBUG) Log.d(TAG, "showPipMenu()");
         mState = STATE_PIP_MENU;
         for (int i = mListeners.size() - 1; i >= 0; --i) {
@@ -250,20 +315,13 @@
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         final ActivityOptions options = ActivityOptions.makeBasic();
         options.setLaunchStackId(PINNED_STACK_ID);
-        options.setLaunchBounds(mMenuModePipBound);
         mContext.startActivity(intent, options.toBundle());
     }
 
-    /**
-     * Adds {@link Listener}.
-     */
     public void addListener(Listener listener) {
         mListeners.add(listener);
     }
 
-    /**
-     * Removes {@link Listener}.
-     */
     public void removeListener(Listener listener) {
         mListeners.remove(listener);
     }
@@ -338,32 +396,36 @@
         @Override
         public void onActivityPinned()  throws RemoteException {
             // Post the message back to the UI thread.
+            if (DEBUG) Log.d(TAG, "onActivityPinned()");
             mHandler.post(mOnActivityPinnedRunnable);
         }
 
         @Override
         public void onPinnedActivityRestartAttempt() {
             // Post the message back to the UI thread.
+            if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
             mHandler.post(mOnPinnedActivityRestartAttempt);
         }
+
+        @Override
+        public void onPinnedStackAnimationEnded() {
+            if (DEBUG) Log.d(TAG, "onPinnedStackAnimationEnded()");
+            mHandler.post(mOnPinnedStackAnimationEnded);
+        }
     }
 
     /**
      * A listener interface to receive notification on changes in PIP.
      */
     public interface Listener {
-        /**
-         * Invoked when a PIPed activity is closed.
-         */
+        /** Invoked when a PIPed activity is closed. */
         void onPipActivityClosed();
-        /**
-         * Invoked when the PIP menu gets shown.
-         */
+        /** Invoked when the PIP menu gets shown. */
         void onShowPipMenu();
-        /**
-         * Invoked when the PIPed activity is returned back to the fullscreen.
-         */
+        /** Invoked when the PIPed activity is returned back to the fullscreen. */
         void onMoveToFullscreen();
+        /** Invoked when we are above to start resizing the Pip. */
+        void onPipResizeAboutToStart();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
index 15c55f5..7e229d4 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java
@@ -54,7 +54,7 @@
         findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                mPipManager.showPipOverlay(true);
+                mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
                 finish();
             }
         });
@@ -62,13 +62,15 @@
 
     @Override
     protected void onDestroy() {
-        mPipManager.removeListener(this);
         super.onDestroy();
+        mPipManager.removeListener(this);
+        mPipManager.resumePipResizing(
+                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
     }
 
     @Override
     public void onBackPressed() {
-        mPipManager.showPipOverlay(true);
+        mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY);
         finish();
     }
 
@@ -84,4 +86,11 @@
     public void onMoveToFullscreen() {
         finish();
     }
+
+    @Override
+    public void onPipResizeAboutToStart() {
+        finish();
+        mPipManager.suspendPipResizing(
+                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
index a0b913a..6f71c92 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOnboardingActivity.java
@@ -62,4 +62,8 @@
     public void onMoveToFullscreen() {
         finish();
     }
+
+    @Override
+    public void onPipResizeAboutToStart() {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
index bc59a8c..7b1764f 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java
@@ -19,8 +19,8 @@
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.Handler;
-import android.view.View;
 
+import android.view.View;
 import com.android.systemui.R;
 
 /**
@@ -30,25 +30,38 @@
     private static final String TAG = "PipOverlayActivity";
     private static final boolean DEBUG = false;
 
-    private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 2000;
+    private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 4000;
 
     private final PipManager mPipManager = PipManager.getInstance();
     private final Handler mHandler = new Handler();
+    private View mGuideOverlayView;
+    private final Runnable mHideGuideOverlayRunnable = new Runnable() {
+        public void run() {
+            mGuideOverlayView.setVisibility(View.INVISIBLE);
+        }
+    };
 
     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
         setContentView(R.layout.tv_pip_overlay);
+        mGuideOverlayView = findViewById(R.id.guide_overlay);
         mPipManager.addListener(this);
-        final View overlayView = findViewById(R.id.guide_overlay);
-        // TODO: apply animation
-        overlayView.setVisibility(View.VISIBLE);
-        mHandler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                overlayView.setVisibility(View.INVISIBLE);
-            }
-        }, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mGuideOverlayView.setVisibility(View.VISIBLE);
+        mHandler.removeCallbacks(mHideGuideOverlayRunnable);
+        mHandler.postDelayed(mHideGuideOverlayRunnable, SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        mHandler.removeCallbacks(mHideGuideOverlayRunnable);
+        finish();
     }
 
     @Override
@@ -56,6 +69,8 @@
         super.onDestroy();
         mHandler.removeCallbacksAndMessages(null);
         mPipManager.removeListener(this);
+        mPipManager.resumePipResizing(
+                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
     }
 
     @Override
@@ -72,4 +87,11 @@
     public void onMoveToFullscreen() {
         finish();
     }
+
+    @Override
+    public void onPipResizeAboutToStart() {
+        finish();
+        mPipManager.suspendPipResizing(
+                PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index e9594a3..5ca24f7 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -526,8 +526,8 @@
             setToMidnight(nextAlarm);
 
             if (weekRange.compareTo(nextAlarm) >= 0) {
-                return ZenModeConfig.toNextAlarmCondition(mContext, now, nextAlarmMs,
-                        ActivityManager.getCurrentUser());
+                return ZenModeConfig.toNextAlarmCondition(mContext, now,
+                        nextAlarmMs, ActivityManager.getCurrentUser());
             }
         }
         return null;
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 3327ec4..3f3f851 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -318,10 +318,10 @@
     OVERVIEW_HISTORY = 275;
 
     // Logged when the user pages through overview.
-    ACTION_OVERVIEW_PAGE = 276;
+    OVERVIEW_PAGE = 276;
 
     // Logged when the user launches a task from overview.
-    ACTION_OVERVIEW_SELECT = 277;
+    OVERVIEW_SELECT = 277;
 
     // Logged when the user views the emergency info.
     ACTION_VIEW_EMERGENCY_INFO = 278;
@@ -353,5 +353,21 @@
     // Logged when the user undocks a previously docked window by long pressing recents while in
     // docked mode.
     ACTION_WINDOW_UNDOCK_LONGPRESS = 286;
+
+    // Logged when the user scrolls through overview manually
+    OVERVIEW_SCROLL = 287;
+
+    // Logged when the overview times out automatically selecting an app
+    OVERVIEW_SELECT_TIMEOUT = 288;
+
+    // Logged when a user dismisses a task in overview
+    OVERVIEW_DISMISS = 289;
+
+    // Logged when the user modifying the notification importance slider.
+    ACTION_MODIFY_IMPORTANCE_SLIDER = 290;
+
+    // Logged when the user saves a modification to notification importance. Negative numbers
+    // indicate the user lowered the importance; positive means they increased it.
+    ACTION_SAVE_IMPORTANCE = 291;
   }
 }
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 3dff37b..3bef19e 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -2346,62 +2346,75 @@
         ALOGD("nScriptGroupCreate, con(%p)", (RsContext)con);
     }
 
+    jlong id = 0;
+
+    RsScriptKernelID* kernelsPtr;
     jint kernelsLen = _env->GetArrayLength(_kernels);
     jlong *jKernelsPtr = _env->GetLongArrayElements(_kernels, nullptr);
+
+    RsScriptKernelID* srcPtr;
+    jint srcLen = _env->GetArrayLength(_src);
+    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
+
+    RsScriptKernelID* dstkPtr;
+    jint dstkLen = _env->GetArrayLength(_dstk);
+    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
+
+    RsScriptKernelID* dstfPtr;
+    jint dstfLen = _env->GetArrayLength(_dstf);
+    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
+
+    RsType* typesPtr;
+    jint typesLen = _env->GetArrayLength(_types);
+    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
+
     if (jKernelsPtr == nullptr) {
         ALOGE("Failed to get Java array elements: kernels");
-        return 0;
+        goto cleanup;
     }
-    RsScriptKernelID* kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
+    if (jSrcPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: src");
+        goto cleanup;
+    }
+    if (jDstkPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: dstk");
+        goto cleanup;
+    }
+    if (jDstfPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: dstf");
+        goto cleanup;
+    }
+    if (jTypesPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: types");
+        goto cleanup;
+    }
+
+    kernelsPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * kernelsLen);
     for(int i = 0; i < kernelsLen; ++i) {
         kernelsPtr[i] = (RsScriptKernelID)jKernelsPtr[i];
     }
 
-    jint srcLen = _env->GetArrayLength(_src);
-    jlong *jSrcPtr = _env->GetLongArrayElements(_src, nullptr);
-    if (jSrcPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: src");
-        return 0;
-    }
-    RsScriptKernelID* srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
+    srcPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * srcLen);
     for(int i = 0; i < srcLen; ++i) {
         srcPtr[i] = (RsScriptKernelID)jSrcPtr[i];
     }
 
-    jint dstkLen = _env->GetArrayLength(_dstk);
-    jlong *jDstkPtr = _env->GetLongArrayElements(_dstk, nullptr);
-    if (jDstkPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: dstk");
-        return 0;
-    }
-    RsScriptKernelID* dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
+    dstkPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstkLen);
     for(int i = 0; i < dstkLen; ++i) {
         dstkPtr[i] = (RsScriptKernelID)jDstkPtr[i];
     }
 
-    jint dstfLen = _env->GetArrayLength(_dstf);
-    jlong *jDstfPtr = _env->GetLongArrayElements(_dstf, nullptr);
-    if (jDstfPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: dstf");
-        return 0;
-    }
-    RsScriptKernelID* dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
+    dstfPtr = (RsScriptKernelID*) malloc(sizeof(RsScriptKernelID) * dstfLen);
     for(int i = 0; i < dstfLen; ++i) {
         dstfPtr[i] = (RsScriptKernelID)jDstfPtr[i];
     }
 
-    jint typesLen = _env->GetArrayLength(_types);
-    jlong *jTypesPtr = _env->GetLongArrayElements(_types, nullptr);
-    if (jTypesPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: types");
-        return 0;
-    }
-    RsType* typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
+    typesPtr = (RsType*) malloc(sizeof(RsType) * typesLen);
     for(int i = 0; i < typesLen; ++i) {
         typesPtr[i] = (RsType)jTypesPtr[i];
     }
 
-    jlong id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
+    id = (jlong)(uintptr_t)rsScriptGroupCreate((RsContext)con,
                                (RsScriptKernelID *)kernelsPtr, kernelsLen * sizeof(RsScriptKernelID),
                                (RsScriptKernelID *)srcPtr, srcLen * sizeof(RsScriptKernelID),
                                (RsScriptKernelID *)dstkPtr, dstkLen * sizeof(RsScriptKernelID),
@@ -2413,11 +2426,24 @@
     free(dstkPtr);
     free(dstfPtr);
     free(typesPtr);
-    _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
-    _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
-    _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
-    _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
-    _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
+
+cleanup:
+    if (jKernelsPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_kernels, jKernelsPtr, 0);
+    }
+    if (jSrcPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_src, jSrcPtr, 0);
+    }
+    if (jDstkPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_dstk, jDstkPtr, 0);
+    }
+    if (jDstfPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_dstf, jDstfPtr, 0);
+    }
+    if (jTypesPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_types, jTypesPtr, 0);
+    }
+
     return id;
 }
 
@@ -2662,45 +2688,61 @@
         ALOGD("nMeshCreate, con(%p)", (RsContext)con);
     }
 
+    jlong id = 0;
+
+    RsAllocation* vtxPtr;
     jint vtxLen = _env->GetArrayLength(_vtx);
     jlong *jVtxPtr = _env->GetLongArrayElements(_vtx, nullptr);
+
+    RsAllocation* idxPtr;
+    jint idxLen = _env->GetArrayLength(_idx);
+    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
+
+    jint primLen = _env->GetArrayLength(_prim);
+    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
+
     if (jVtxPtr == nullptr) {
         ALOGE("Failed to get Java array elements: vtx");
-        return 0;
+        goto cleanupMesh;
     }
-    RsAllocation* vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
+    if (jIdxPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: idx");
+        goto cleanupMesh;
+    }
+    if (primPtr == nullptr) {
+        ALOGE("Failed to get Java array elements: prim");
+        goto cleanupMesh;
+    }
+
+    vtxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * vtxLen);
     for(int i = 0; i < vtxLen; ++i) {
         vtxPtr[i] = (RsAllocation)(uintptr_t)jVtxPtr[i];
     }
 
-    jint idxLen = _env->GetArrayLength(_idx);
-    jlong *jIdxPtr = _env->GetLongArrayElements(_idx, nullptr);
-    if (jIdxPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: idx");
-        return 0;
-    }
-    RsAllocation* idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
+    idxPtr = (RsAllocation*) malloc(sizeof(RsAllocation) * idxLen);
     for(int i = 0; i < idxLen; ++i) {
         idxPtr[i] = (RsAllocation)(uintptr_t)jIdxPtr[i];
     }
 
-    jint primLen = _env->GetArrayLength(_prim);
-    jint *primPtr = _env->GetIntArrayElements(_prim, nullptr);
-    if (primPtr == nullptr) {
-        ALOGE("Failed to get Java array elements: prim");
-        return 0;
-    }
-
-    jlong id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
-                               (RsAllocation *)vtxPtr, vtxLen,
-                               (RsAllocation *)idxPtr, idxLen,
-                               (uint32_t *)primPtr, primLen);
+    id = (jlong)(uintptr_t)rsMeshCreate((RsContext)con,
+                                        (RsAllocation *)vtxPtr, vtxLen,
+                                        (RsAllocation *)idxPtr, idxLen,
+                                        (uint32_t *)primPtr, primLen);
 
     free(vtxPtr);
     free(idxPtr);
-    _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
-    _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
-    _env->ReleaseIntArrayElements(_prim, primPtr, 0);
+
+cleanupMesh:
+    if (jVtxPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_vtx, jVtxPtr, 0);
+    }
+    if (jIdxPtr != nullptr) {
+        _env->ReleaseLongArrayElements(_idx, jIdxPtr, 0);
+    }
+    if (primPtr != nullptr) {
+        _env->ReleaseIntArrayElements(_prim, primPtr, 0);
+    }
+
     return id;
 }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
index b79a7ba..ad70853 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java
@@ -110,9 +110,25 @@
     // The minimal score for accepting a predicted gesture.
     private static final float MIN_PREDICTION_SCORE = 2.0f;
 
+    // Distance a finger must travel before we decide if it is a gesture or not.
     private static final int GESTURE_CONFIRM_MM = 10;
-    private static final long CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS = 1000;
-    private static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 500;
+
+    // Time threshold used to determine if an interaction is a gesture or not.
+    // If the first movement of 1cm takes longer than this value, we assume it's
+    // a slow movement, and therefore not a gesture.
+    //
+    // This value was determined by measuring the time for the first 1cm
+    // movement when gesturing, and touch exploring.  Based on user testing,
+    // all gestures started with the initial movement taking less than 100ms.
+    // When touch exploring, the first movement almost always takes longer than
+    // 200ms.  From this data, 150ms seems the best value to decide what
+    // kind of interaction it is.
+    private static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 150;
+
+    // Time threshold used to determine if a gesture should be cancelled.  If
+    // the finger pauses for longer than this delay, the ongoing gesture is
+    // cancelled.
+    private static final long CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS = 500;
 
     AccessibilityGestureDetector(Context context, Listener listener) {
         mListener = listener;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 232c080..3e7466f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -200,10 +200,6 @@
         }
     }
 
-    public MotionEventInjector getMotionEventInjector() {
-        return mMotionEventInjector;
-    }
-
     /**
      * Gets current event stream state associated with an input event.
      * @return The event stream state that should be used for the event. Null if the event should
@@ -279,6 +275,9 @@
 
     private void processBatchedEvents(long frameNanos) {
         MotionEventHolder current = mEventQueue;
+        if (current == null) {
+            return;
+        }
         while (current.next != null) {
             current = current.next;
         }
@@ -407,6 +406,9 @@
     }
 
     private void disableFeatures() {
+        // Give the features a chance to process any batched events so we'll keep a consistent
+        // event stream
+        processBatchedEvents(Long.MAX_VALUE);
         if (mMotionEventInjector != null) {
             mAms.setMotionEventInjector(null);
             mMotionEventInjector.onDestroy();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 53504cc..4be6833 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -52,7 +52,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -129,6 +128,10 @@
 
     private static final int WAIT_WINDOWS_TIMEOUT_MILLIS = 5000;
 
+    // TODO: Restructure service initialization so services aren't connected before all of
+    //       their capabilities are ready.
+    private static final int WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS = 1000;
+
     private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
         "registerUiTestAutomationService";
 
@@ -650,7 +653,7 @@
             userState.mUiAutomationFlags = flags;
             userState.mIsAccessibilityEnabled = true;
             userState.mInstalledServices.add(accessibilityServiceInfo);
-            if (userState.isUiAutomationSuppressingOtherServices()) {
+            if ((flags & UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES) == 0) {
                 // Set the temporary state.
                 userState.mIsTouchExplorationEnabled = false;
                 userState.mIsEnhancedWebAccessibilityEnabled = false;
@@ -794,6 +797,8 @@
     void setMotionEventInjector(MotionEventInjector motionEventInjector) {
         synchronized (mLock) {
             mMotionEventInjector = motionEventInjector;
+            // We may be waiting on this object being set
+            mLock.notifyAll();
         }
     }
 
@@ -2655,10 +2660,24 @@
         @Override
         public void sendMotionEvents(int sequence, ParceledListSlice events) {
             synchronized (mLock) {
-                if (mSecurityPolicy.canPerformGestures(this) && (mMotionEventInjector != null)) {
-                    mMotionEventInjector.injectEvents((List<MotionEvent>) events.getList(),
-                            mServiceInterface, sequence);
-                    return;
+                if (mSecurityPolicy.canPerformGestures(this)) {
+                    final long endMillis =
+                            SystemClock.uptimeMillis() + WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS;
+                    while ((mMotionEventInjector == null)
+                            && (SystemClock.uptimeMillis() < endMillis)) {
+                        try {
+                            mLock.wait(endMillis - SystemClock.uptimeMillis());
+                        } catch (InterruptedException ie) {
+                            /* ignore */
+                        }
+                    }
+                    if (mMotionEventInjector != null) {
+                        mMotionEventInjector.injectEvents((List<MotionEvent>) events.getList(),
+                                mServiceInterface, sequence);
+                        return;
+                    } else {
+                        Slog.e(LOG_TAG, "MotionEventInjector installation timed out");
+                    }
                 }
             }
             try {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 29801b3..4646f3c 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -493,9 +493,8 @@
                 continue;
             }
             try {
-                ApplicationInfo ai = mPackageManager.getApplicationInfo(
-                        provider.info.provider.getPackageName(), 0, provider.getUserId());
-                boolean suspended = (ai.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
+                boolean suspended = mPackageManager.isPackageSuspendedForUser(
+                        provider.info.provider.getPackageName(), provider.getUserId());
                 if (provider.setMaskedBySuspendedPackageLocked(suspended)) {
                     if (provider.isMaskedLocked()) {
                         maskWidgetsViewsLocked(provider);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 5e948b1..eaee1d3 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -87,6 +87,7 @@
 import android.util.AtomicFile;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.StringBuilderPrinter;
@@ -142,6 +143,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.zip.Deflater;
 import java.util.zip.DeflaterOutputStream;
 import java.util.zip.InflaterInputStream;
@@ -786,8 +788,9 @@
             case MSG_OP_COMPLETE:
             {
                 try {
-                    BackupRestoreTask task = (BackupRestoreTask) msg.obj;
-                    task.operationComplete(msg.arg1);
+                    Pair<BackupRestoreTask, Long> taskWithResult =
+                            (Pair<BackupRestoreTask, Long>) msg.obj;
+                    taskWithResult.first.operationComplete(taskWithResult.second);
                 } catch (ClassCastException e) {
                     Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
                 }
@@ -1044,7 +1047,7 @@
 
         // If Encrypted file systems is enabled or disabled, this call will return the
         // correct directory.
-        mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
+        mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
         mBaseStateDir.mkdirs();
         if (!SELinux.restorecon(mBaseStateDir)) {
             Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
@@ -2416,7 +2419,7 @@
                 PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
                         PackageManager.GET_SIGNATURES);
                 if (!appIsEligibleForBackup(packageInfo.applicationInfo)) {
-                    sendBackupOnResult(observer, packageName,
+                    sendBackupOnPackageResult(observer, packageName,
                             BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     continue;
                 }
@@ -2426,7 +2429,8 @@
                     kvBackupList.add(packageInfo.packageName);
                 }
             } catch (NameNotFoundException e) {
-                sendBackupOnResult(observer, packageName, BackupManager.ERROR_PACKAGE_NOT_FOUND);
+                sendBackupOnPackageResult(observer, packageName,
+                        BackupManager.ERROR_PACKAGE_NOT_FOUND);
             }
         }
         EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
@@ -2459,7 +2463,7 @@
         void execute();
 
         // An operation that wanted a callback has completed
-        void operationComplete(int result);
+        void operationComplete(long result);
 
         // An operation that wanted a callback has timed out
         void handleTimeout();
@@ -2758,8 +2762,8 @@
                     addBackupTrace("skipping - not eligible, completion is noop");
                     // Shouldn't happen in case of requested backup, as pre-check was done in
                     // #requestBackup(), except to app update done concurrently
-                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
-                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2773,8 +2777,8 @@
                     addBackupTrace("skipping - fullBackupOnly, completion is noop");
                     // Shouldn't happen in case of requested backup, as pre-check was done in
                     // #requestBackup()
-                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
-                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2784,8 +2788,8 @@
                     // and not yet launched out of that state, so just as it won't
                     // receive broadcasts, we won't run it for backup.
                     addBackupTrace("skipping - stopped");
-                    sendBackupOnResult(mObserver, mCurrentPackage.packageName,
-                        BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                            BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     executeNextState(BackupState.RUNNING_QUEUE);
                     return;
                 }
@@ -2833,14 +2837,14 @@
                         dataChangedImpl(request.packageName);
                         mStatus = BackupTransport.TRANSPORT_OK;
                         if (mQueue.isEmpty()) nextState = BackupState.FINAL;
-                        sendBackupOnResult(mObserver, mCurrentPackage.packageName,
-                            BackupManager.ERROR_AGENT_FAILURE);
+                        sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                BackupManager.ERROR_AGENT_FAILURE);
                     } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
                         // Failed lookup of the app, so we couldn't bring up an agent, but
                         // we're otherwise fine.  Just drop it and go on to the next as usual.
                         mStatus = BackupTransport.TRANSPORT_OK;
-                        sendBackupOnResult(mObserver, mCurrentPackage.packageName,
-                            BackupManager.ERROR_PACKAGE_NOT_FOUND);
+                        sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+                                BackupManager.ERROR_PACKAGE_NOT_FOUND);
                     } else {
                         // Transport-level failure means we reenqueue everything
                         revertAndEndBackup();
@@ -3094,7 +3098,7 @@
         }
 
         @Override
-        public void operationComplete(int unusedResult) {
+        public void operationComplete(long unusedResult) {
             // The agent reported back to us!
 
             if (mBackupData == null) {
@@ -3132,7 +3136,7 @@
                                 EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
                                         "bad key");
                                 mBackupHandler.removeMessages(MSG_TIMEOUT);
-                                sendBackupOnResult(mObserver, pkgName,
+                                sendBackupOnPackageResult(mObserver, pkgName,
                                         BackupManager.ERROR_AGENT_FAILURE);
                                 agentErrorCleanup();
                                 // agentErrorCleanup() implicitly executes next state properly
@@ -3207,7 +3211,7 @@
                     // with the new state file it just created.
                     mBackupDataName.delete();
                     mNewStateName.renameTo(mSavedStateName);
-                    sendBackupOnResult(mObserver, pkgName, BackupManager.SUCCESS);
+                    sendBackupOnPackageResult(mObserver, pkgName, BackupManager.SUCCESS);
                     EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
                     logBackupComplete(pkgName);
                 } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
@@ -3215,20 +3219,22 @@
                     // back but proceed with running the rest of the queue.
                     mBackupDataName.delete();
                     mNewStateName.delete();
-                    sendBackupOnResult(mObserver, pkgName,
+                    sendBackupOnPackageResult(mObserver, pkgName,
                             BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                     EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
                 } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
-                    sendBackupOnResult(mObserver, pkgName,
+                    sendBackupOnPackageResult(mObserver, pkgName,
                             BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
                     EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
                 } else {
                     // Actual transport-level failure to communicate the data to the backend
-                    sendBackupOnResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_ABORTED);
+                    sendBackupOnPackageResult(mObserver, pkgName,
+                            BackupManager.ERROR_TRANSPORT_ABORTED);
                     EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 }
             } catch (Exception e) {
-                sendBackupOnResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_ABORTED);
+                sendBackupOnPackageResult(mObserver, pkgName,
+                        BackupManager.ERROR_TRANSPORT_ABORTED);
                 Slog.e(TAG, "Transport error backing up " + pkgName, e);
                 EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 mStatus = BackupTransport.TRANSPORT_ERROR;
@@ -3491,18 +3497,18 @@
          */
         int preflightFullBackup(PackageInfo pkg, IBackupAgent agent);
 
-        long expectedSize();
+        long getExpectedSizeOrErrorCode();
     };
 
     class FullBackupEngine {
         OutputStream mOutput;
         FullBackupPreflight mPreflightHook;
-        IFullBackupRestoreObserver mObserver;
         IBackupAgent mAgent;
         File mFilesDir;
         File mManifestFile;
         File mMetadataFile;
         boolean mIncludeApks;
+        PackageInfo mPkg;
 
         class FullBackupRunner implements Runnable {
             PackageInfo mPackage;
@@ -3514,8 +3520,8 @@
             boolean mWriteManifest;
 
             FullBackupRunner(PackageInfo pack, IBackupAgent agent, ParcelFileDescriptor pipe,
-                    int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
-                            throws IOException {
+                             int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
+                    throws IOException {
                 mPackage = pack;
                 mWidgetData = widgetData;
                 mAgent = agent;
@@ -3571,76 +3577,78 @@
             }
         }
 
-        FullBackupEngine(OutputStream output, String packageName, FullBackupPreflight preflightHook,
-                boolean alsoApks) {
+        FullBackupEngine(OutputStream output, FullBackupPreflight preflightHook, PackageInfo pkg,
+                         boolean alsoApks) {
             mOutput = output;
             mPreflightHook = preflightHook;
+            mPkg = pkg;
             mIncludeApks = alsoApks;
             mFilesDir = new File("/data/system");
             mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
             mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
         }
 
-        public int backupOnePackage(PackageInfo pkg) throws RemoteException {
-            int result = BackupTransport.TRANSPORT_OK;
-            Slog.d(TAG, "Binding to full backup agent : " + pkg.packageName);
+        public int preflightCheck() throws RemoteException {
+            if (mPreflightHook == null) {
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "No preflight check");
+                }
+                return BackupTransport.TRANSPORT_OK;
+            }
+            if (initializeAgent()) {
+                int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
+                if (MORE_DEBUG) {
+                    Slog.v(TAG, "preflight returned " + result);
+                }
+                return result;
+            } else {
+                Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
+                return BackupTransport.AGENT_ERROR;
+            }
+        }
 
-            mAgent = bindToAgentSynchronous(pkg.applicationInfo,
-                    IApplicationThread.BACKUP_MODE_FULL);
-            if (mAgent != null) {
+        public int backupOnePackage() throws RemoteException {
+            int result = BackupTransport.AGENT_ERROR;
+
+            if (initializeAgent()) {
                 ParcelFileDescriptor[] pipes = null;
                 try {
-                    // Call the preflight hook, if any
-                    if (mPreflightHook != null) {
-                        result = mPreflightHook.preflightFullBackup(pkg, mAgent);
+                    pipes = ParcelFileDescriptor.createPipe();
+
+                    ApplicationInfo app = mPkg.applicationInfo;
+                    final boolean isSharedStorage =
+                            mPkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+                    final boolean sendApk = mIncludeApks
+                            && !isSharedStorage
+                            && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
+                            && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
+                            (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+
+                    // TODO: http://b/22388012
+                    byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(mPkg.packageName,
+                            UserHandle.USER_SYSTEM);
+
+                    final int token = generateToken();
+                    FullBackupRunner runner = new FullBackupRunner(mPkg, mAgent, pipes[1],
+                            token, sendApk, !isSharedStorage, widgetBlob);
+                    pipes[1].close();   // the runner has dup'd it
+                    pipes[1] = null;
+                    Thread t = new Thread(runner, "app-data-runner");
+                    t.start();
+
+                    // Now pull data from the app and stuff it into the output
+                    routeSocketDataToOutput(pipes[0], mOutput);
+
+                    if (!waitUntilOperationComplete(token)) {
+                        Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
+                    } else {
                         if (MORE_DEBUG) {
-                            Slog.v(TAG, "preflight returned " + result);
+                            Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
                         }
-                    }
-
-                    // If we're still good to go after preflighting, start moving data
-                    if (result == BackupTransport.TRANSPORT_OK) {
-                        pipes = ParcelFileDescriptor.createPipe();
-
-                        ApplicationInfo app = pkg.applicationInfo;
-                        final boolean isSharedStorage = pkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
-                        final boolean sendApk = mIncludeApks
-                                && !isSharedStorage
-                                && ((app.privateFlags & ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK) == 0)
-                                && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
-                                (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
-
-                        // TODO: http://b/22388012
-                        byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(pkg.packageName,
-                                UserHandle.USER_SYSTEM);
-
-                        final int token = generateToken();
-                        FullBackupRunner runner = new FullBackupRunner(pkg, mAgent, pipes[1],
-                                token, sendApk, !isSharedStorage, widgetBlob);
-                        pipes[1].close();   // the runner has dup'd it
-                        pipes[1] = null;
-                        Thread t = new Thread(runner, "app-data-runner");
-                        t.start();
-
-                        // Now pull data from the app and stuff it into the output
-                        try {
-                            routeSocketDataToOutput(pipes[0], mOutput);
-                        } catch (IOException e) {
-                            Slog.i(TAG, "Caught exception reading from agent", e);
-                            result = BackupTransport.AGENT_ERROR;
-                        }
-
-                        if (!waitUntilOperationComplete(token)) {
-                            Slog.e(TAG, "Full backup failed on package " + pkg.packageName);
-                            result = BackupTransport.AGENT_ERROR;
-                        } else {
-                            if (MORE_DEBUG) {
-                                Slog.d(TAG, "Full package backup success: " + pkg.packageName);
-                            }
-                        }
+                        result = BackupTransport.TRANSPORT_OK;
                     }
                 } catch (IOException e) {
-                    Slog.e(TAG, "Error backing up " + pkg.packageName, e);
+                    Slog.e(TAG, "Error backing up " + mPkg.packageName, e);
                     result = BackupTransport.AGENT_ERROR;
                 } finally {
                     try {
@@ -3656,15 +3664,14 @@
                     }
                 }
             } else {
-                Slog.w(TAG, "Unable to bind to full agent for " + pkg.packageName);
-                result = BackupTransport.AGENT_ERROR;
+                Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
             }
-            tearDown(pkg);
+            tearDown();
             return result;
         }
 
         public void sendQuotaExceeded(final long backupDataBytes, final long quotaBytes) {
-            if (mAgent != null) {
+            if (initializeAgent()) {
                 try {
                     mAgent.doQuotaExceeded(backupDataBytes, quotaBytes);
                 } catch (RemoteException e) {
@@ -3673,6 +3680,17 @@
             }
         }
 
+        private boolean initializeAgent() {
+            if (mAgent == null) {
+                if (MORE_DEBUG) {
+                    Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
+                }
+                mAgent = bindToAgentSynchronous(mPkg.applicationInfo,
+                        IApplicationThread.BACKUP_MODE_FULL);
+            }
+            return mAgent != null;
+        }
+
         private void writeApkToBackup(PackageInfo pkg, FullBackupDataOutput output) {
             // Forward-locked apps, system-bundled .apks, etc are filtered out before we get here
             // TODO: handle backing up split APKs
@@ -3789,9 +3807,9 @@
             destination.setLastModified(0);
         }
 
-        private void tearDown(PackageInfo pkg) {
-            if (pkg != null) {
-                final ApplicationInfo app = pkg.applicationInfo;
+        private void tearDown() {
+            if (mPkg != null) {
+                final ApplicationInfo app = mPkg.applicationInfo;
                 if (app != null) {
                     tearDownAgentAndKill(app);
                 }
@@ -4160,9 +4178,10 @@
                     final boolean isSharedStorage =
                             pkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
 
-                    mBackupEngine = new FullBackupEngine(out, pkg.packageName, null, mIncludeApks);
+                    mBackupEngine = new FullBackupEngine(out, null, pkg, mIncludeApks);
                     sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
-                    mBackupEngine.backupOnePackage(pkg);
+                    // Don't need to check preflight result as there is no preflight hook.
+                    mBackupEngine.backupOnePackage();
 
                     // after the app's agent runs to handle its private filesystem
                     // contents, back up any OBB content it has on its behalf.
@@ -4238,7 +4257,7 @@
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "Ignoring ineligible package " + pkg);
                         }
-                        sendBackupOnResult(mBackupObserver, pkg,
+                        sendBackupOnPackageResult(mBackupObserver, pkg,
                             BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     } else if (!appGetsFullBackup(info)) {
@@ -4248,7 +4267,7 @@
                             Slog.d(TAG, "Ignoring full-data backup of key/value participant "
                                     + pkg);
                         }
-                        sendBackupOnResult(mBackupObserver, pkg,
+                        sendBackupOnPackageResult(mBackupObserver, pkg,
                                 BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     } else if (appIsStopped(info.applicationInfo)) {
@@ -4258,7 +4277,7 @@
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "Ignoring stopped package " + pkg);
                         }
-                        sendBackupOnResult(mBackupObserver, pkg,
+                        sendBackupOnPackageResult(mBackupObserver, pkg,
                                 BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                         continue;
                     }
@@ -4281,8 +4300,8 @@
             // Pipe through which we write data to the transport
             ParcelFileDescriptor[] transportPipes = null;
 
-            PackageInfo currentPackage;
             long backoff = 0;
+            int backupRunStatus = BackupManager.SUCCESS;
 
             try {
                 if (!mEnabled || !mProvisioned) {
@@ -4292,14 +4311,14 @@
                                 + " p=" + mProvisioned + "; ignoring");
                     }
                     mUpdateSchedule = false;
-                    sendBackupFinished(mBackupObserver, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+                    backupRunStatus = BackupManager.ERROR_BACKUP_NOT_ALLOWED;
                     return;
                 }
 
                 IBackupTransport transport = getTransport(mCurrentTransport);
                 if (transport == null) {
                     Slog.w(TAG, "Transport not present; full data backup not performed");
-                    sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+                    backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
                     return;
                 }
 
@@ -4307,21 +4326,20 @@
                 final int N = mPackages.size();
                 final byte[] buffer = new byte[8192];
                 for (int i = 0; i < N; i++) {
-                    currentPackage = mPackages.get(i);
+                    PackageInfo currentPackage = mPackages.get(i);
+                    String packageName = currentPackage.packageName;
                     if (DEBUG) {
-                        Slog.i(TAG, "Initiating full-data transport backup of "
-                                + currentPackage.packageName);
+                        Slog.i(TAG, "Initiating full-data transport backup of " + packageName);
                     }
-                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE,
-                            currentPackage.packageName);
+                    EventLog.writeEvent(EventLogTags.FULL_BACKUP_PACKAGE, packageName);
 
                     transportPipes = ParcelFileDescriptor.createPipe();
 
                     // Tell the transport the data's coming
                     int flags = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
-                    int result = transport.performFullBackup(currentPackage,
+                    int backupPackageStatus = transport.performFullBackup(currentPackage,
                             transportPipes[0], flags);
-                    if (result == BackupTransport.TRANSPORT_OK) {
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
                         // The transport has its own copy of the read end of the pipe,
                         // so close ours now
                         transportPipes[0].close();
@@ -4329,10 +4347,9 @@
 
                         // Now set up the backup engine / data source end of things
                         enginePipes = ParcelFileDescriptor.createPipe();
-                        CountDownLatch runnerLatch = new CountDownLatch(1);
                         SinglePackageBackupRunner backupRunner =
                                 new SinglePackageBackupRunner(enginePipes[1], currentPackage,
-                                        transport, runnerLatch);
+                                        transport);
                         // The runner dup'd the pipe half, so we close it here
                         enginePipes[1].close();
                         enginePipes[1] = null;
@@ -4348,49 +4365,55 @@
                         FileOutputStream out = new FileOutputStream(
                                 transportPipes[1].getFileDescriptor());
                         long totalRead = 0;
-                        final long expectedSize = backupRunner.expectedSize();
-                        if (expectedSize < 0) {
-                            result = BackupTransport.AGENT_ERROR;
-                            sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                                    BackupManager.ERROR_AGENT_FAILURE);
-                        }
-                        int nRead = 0;
-                        do {
-                            if (!mKeepRunning.get()) {
-                                if (DEBUG_SCHEDULING) {
-                                    Slog.i(TAG, "Full backup task told to stop");
-                                }
-                                break;
-                            }
-                            nRead = in.read(buffer);
+                        final long preflightResult = backupRunner.getPreflightResultBlocking();
+                        // Preflight result is negative if some error happened on preflight.
+                        if (preflightResult < 0) {
                             if (MORE_DEBUG) {
-                                Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+                                Slog.d(TAG, "Backup error after preflight of package "
+                                        + packageName + ": " + preflightResult
+                                        + ", not running backup.");
                             }
-                            if (nRead > 0) {
-                                out.write(buffer, 0, nRead);
-                                result = transport.sendBackupData(nRead);
-                                totalRead += nRead;
-                                if (mBackupObserver != null && expectedSize > 0) {
-                                    sendBackupOnUpdate(mBackupObserver, currentPackage.packageName,
-                                        new BackupProgress(expectedSize, totalRead));
+                            backupPackageStatus = (int) preflightResult;
+                        } else {
+                            int nRead = 0;
+                            do {
+                                if (!mKeepRunning.get()) {
+                                    if (DEBUG_SCHEDULING) {
+                                        Slog.i(TAG, "Full backup task told to stop");
+                                    }
+                                    break;
                                 }
-                            }
-                        } while (nRead > 0 && result == BackupTransport.TRANSPORT_OK);
+                                nRead = in.read(buffer);
+                                if (MORE_DEBUG) {
+                                    Slog.v(TAG, "in.read(buffer) from app: " + nRead);
+                                }
+                                if (nRead > 0) {
+                                    out.write(buffer, 0, nRead);
+                                    backupPackageStatus = transport.sendBackupData(nRead);
+                                    totalRead += nRead;
+                                    if (mBackupObserver != null && preflightResult > 0) {
+                                        sendBackupOnUpdate(mBackupObserver, packageName,
+                                                new BackupProgress(preflightResult, totalRead));
+                                    }
+                                }
+                            } while (nRead > 0
+                                    && backupPackageStatus == BackupTransport.TRANSPORT_OK);
 
-                        if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
-                            long quota = transport.getBackupQuota(currentPackage.packageName, true);
-                            if (MORE_DEBUG) {
-                                Slog.d(TAG, "Package hit quota limit " + currentPackage.packageName
+                            // Despite preflight succeeded, package still can hit quota on flight.
+                            if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                                long quota = transport.getBackupQuota(packageName, true);
+                                Slog.w(TAG, "Package hit quota limit in-flight " + packageName
                                         + ": " + totalRead + " of " + quota);
+                                backupRunner.sendQuotaExceeded(totalRead, quota);
                             }
-                            backupRunner.sendQuotaExceeded(totalRead, quota);
                         }
 
+
                         // If we've lost our running criteria, tell the transport to cancel
                         // and roll back this (partial) backup payload; otherwise tell it
                         // that we've reached the clean finish state.
                         if (!mKeepRunning.get()) {
-                            result = BackupTransport.TRANSPORT_ERROR;
+                            backupPackageStatus = BackupTransport.TRANSPORT_ERROR;
                             transport.cancelFullBackup();
                         } else {
                             // If we were otherwise in a good state, now interpret the final
@@ -4398,18 +4421,28 @@
                             // failure case already, preserve that result and ignore whatever
                             // finishBackup() reports.
                             final int finishResult = transport.finishBackup();
-                            if (result == BackupTransport.TRANSPORT_OK) {
-                                result = finishResult;
+                            if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
+                                backupPackageStatus = finishResult;
                             }
                         }
 
-                        if (MORE_DEBUG) {
-                            Slog.i(TAG, "Done trying to send backup data: result=" + result);
+                        // We still could fail in backup runner thread, getting result from there.
+                        int backupRunnerResult = backupRunner.getBackupResultBlocking();
+                        if (backupPackageStatus != BackupTransport.TRANSPORT_ERROR
+                                && backupRunnerResult != BackupTransport.TRANSPORT_OK) {
+                            // If there was an error in runner thread and
+                            // not TRANSPORT_ERROR here, overwrite it.
+                            backupPackageStatus = backupRunnerResult;
                         }
 
-                        if (result != BackupTransport.TRANSPORT_OK) {
-                            Slog.e(TAG, "Error " + result
-                                    + " backing up " + currentPackage.packageName);
+                        if (MORE_DEBUG) {
+                            Slog.i(TAG, "Done trying to send backup data: result="
+                                    + backupPackageStatus);
+                        }
+
+                        if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                            Slog.e(TAG, "Error " + backupPackageStatus + " backing up "
+                                    + packageName);
                         }
 
                         // Also ask the transport how long it wants us to wait before
@@ -4424,55 +4457,61 @@
                     // Roll this package to the end of the backup queue if we're
                     // in a queue-driven mode (regardless of success/failure)
                     if (mUpdateSchedule) {
-                        enqueueFullBackup(currentPackage.packageName,
-                                System.currentTimeMillis());
+                        enqueueFullBackup(packageName, System.currentTimeMillis());
                     }
 
-                    if (result == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                            BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+                    if (backupPackageStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+                        sendBackupOnPackageResult(mBackupObserver, packageName,
+                                BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
                         if (DEBUG) {
-                            Slog.i(TAG, "Transport rejected backup of "
-                                    + currentPackage.packageName
+                            Slog.i(TAG, "Transport rejected backup of " + packageName
                                     + ", skipping");
                         }
-                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE,
-                                currentPackage.packageName, "transport rejected");
-                        // do nothing, clean up, and continue looping
-                    } else if (result == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                            BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
-                        Slog.w(TAG, "Transport quota exceeded; aborting backup: " + result);
-                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
-                                currentPackage.packageName);
-                        return;
-                    } else if (result != BackupTransport.TRANSPORT_OK) {
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_AGENT_FAILURE, packageName,
+                                "transport rejected");
+                        // Do nothing, clean up, and continue looping.
+                    } else if (backupPackageStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+                        sendBackupOnPackageResult(mBackupObserver, packageName,
+                                BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+                        if (DEBUG) {
+                            Slog.i(TAG, "Transport quota exceeded for package: " + packageName);
+                            EventLog.writeEvent(EventLogTags.FULL_BACKUP_QUOTA_EXCEEDED,
+                                    packageName);
+                        }
+                        // Do nothing, clean up, and continue looping.
+                    } else if (backupPackageStatus == BackupTransport.AGENT_ERROR) {
+                        sendBackupOnPackageResult(mBackupObserver, packageName,
+                                BackupManager.ERROR_AGENT_FAILURE);
+                        Slog.w(TAG, "Application failure for package: " + packageName);
+                        EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+                        // Do nothing, clean up, and continue looping.
+                    } else if (backupPackageStatus != BackupTransport.TRANSPORT_OK) {
+                        sendBackupOnPackageResult(mBackupObserver, packageName,
                             BackupManager.ERROR_TRANSPORT_ABORTED);
-                        Slog.w(TAG, "Transport failed; aborting backup: " + result);
+                        Slog.w(TAG, "Transport failed; aborting backup: " + backupPackageStatus);
                         EventLog.writeEvent(EventLogTags.FULL_BACKUP_TRANSPORT_FAILURE);
+                        // Abort entire backup pass.
+                        backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
                         return;
                     } else {
                         // Success!
-                        sendBackupOnResult(mBackupObserver, currentPackage.packageName,
-                            BackupManager.SUCCESS);
-                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS,
-                                currentPackage.packageName);
-                        logBackupComplete(currentPackage.packageName);
+                        sendBackupOnPackageResult(mBackupObserver, packageName,
+                                BackupManager.SUCCESS);
+                        EventLog.writeEvent(EventLogTags.FULL_BACKUP_SUCCESS, packageName);
+                        logBackupComplete(packageName);
                     }
                     cleanUpPipes(transportPipes);
                     cleanUpPipes(enginePipes);
-                    currentPackage = null;
-                }
-
-                sendBackupFinished(mBackupObserver, BackupManager.SUCCESS);
-                if (DEBUG) {
-                    Slog.i(TAG, "Full backup completed.");
                 }
             } catch (Exception e) {
-                sendBackupFinished(mBackupObserver, BackupManager.ERROR_TRANSPORT_ABORTED);
+                backupRunStatus = BackupManager.ERROR_TRANSPORT_ABORTED;
                 Slog.w(TAG, "Exception trying full transport backup", e);
             } finally {
+                if (DEBUG) {
+                    Slog.i(TAG, "Full backup completed with status: " + backupRunStatus);
+                }
+                sendBackupFinished(mBackupObserver, backupRunStatus);
+
                 cleanUpPipes(transportPipes);
                 cleanUpPipes(enginePipes);
 
@@ -4524,7 +4563,7 @@
         // a standalone thread.  The  runner owns this half of the pipe, and closes
         // it to indicate EOD to the other end.
         class SinglePackageBackupPreflight implements BackupRestoreTask, FullBackupPreflight {
-            final AtomicInteger mResult = new AtomicInteger();
+            final AtomicLong mResult = new AtomicLong();
             final CountDownLatch mLatch = new CountDownLatch(1);
             final IBackupTransport mTransport;
 
@@ -4546,7 +4585,11 @@
 
                     // now wait to get our result back
                     mLatch.await();
-                    int totalSize = mResult.get();
+                    long totalSize = mResult.get();
+                    // If preflight timeouted, mResult will contain error code as int.
+                    if (totalSize < 0) {
+                        return (int) totalSize;
+                    }
                     if (MORE_DEBUG) {
                         Slog.v(TAG, "Got preflight response; size=" + totalSize);
                     }
@@ -4573,7 +4616,7 @@
             }
 
             @Override
-            public void operationComplete(int result) {
+            public void operationComplete(long result) {
                 // got the callback, and our preflightFullBackup() method is waiting for the result
                 if (MORE_DEBUG) {
                     Slog.i(TAG, "Preflight op complete, result=" + result);
@@ -4592,7 +4635,7 @@
             }
 
             @Override
-            public long expectedSize() {
+            public long getExpectedSizeOrErrorCode() {
                 try {
                     mLatch.await();
                     return mResult.get();
@@ -4606,28 +4649,41 @@
             final ParcelFileDescriptor mOutput;
             final PackageInfo mTarget;
             final FullBackupPreflight mPreflight;
-            final CountDownLatch mLatch;
+            final CountDownLatch mPreflightLatch;
+            final CountDownLatch mBackupLatch;
             private FullBackupEngine mEngine;
+            private volatile int mPreflightResult;
+            private volatile int mBackupResult;
 
             SinglePackageBackupRunner(ParcelFileDescriptor output, PackageInfo target,
-                    IBackupTransport transport, CountDownLatch latch) throws IOException {
+                    IBackupTransport transport) throws IOException {
                 mOutput = ParcelFileDescriptor.dup(output.getFileDescriptor());
                 mTarget = target;
                 mPreflight = new SinglePackageBackupPreflight(transport);
-                mLatch = latch;
+                mPreflightLatch = new CountDownLatch(1);
+                mBackupLatch = new CountDownLatch(1);
+                mPreflightResult = BackupTransport.TRANSPORT_OK;
+                mBackupResult = BackupTransport.TRANSPORT_OK;
             }
 
             @Override
             public void run() {
+                FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
+                mEngine = new FullBackupEngine(out, mPreflight, mTarget, false);
                 try {
-                    FileOutputStream out = new FileOutputStream(mOutput.getFileDescriptor());
-                    mEngine = new FullBackupEngine(out, mTarget.packageName,
-                            mPreflight, false);
-                    mEngine.backupOnePackage(mTarget);
+                    try {
+                        mPreflightResult = mEngine.preflightCheck();
+                    } finally {
+                        mPreflightLatch.countDown();
+                    }
+                    // If there is no error on preflight, continue backup.
+                    if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                        mBackupResult = mEngine.backupOnePackage();
+                    }
                 } catch (Exception e) {
-                    Slog.e(TAG, "Exception during full package backup of " + mTarget);
+                    Slog.e(TAG, "Exception during full package backup of " + mTarget.packageName);
                 } finally {
-                    mLatch.countDown();
+                    mBackupLatch.countDown();
                     try {
                         mOutput.close();
                     } catch (IOException e) {
@@ -4640,8 +4696,28 @@
                 mEngine.sendQuotaExceeded(backupDataBytes, quotaBytes);
             }
 
-            long expectedSize() {
-                return mPreflight.expectedSize();
+            // If preflight succeeded, returns positive number - preflight size,
+            // otherwise return negative error code.
+            long getPreflightResultBlocking() {
+                try {
+                    mPreflightLatch.await();
+                    if (mPreflightResult == BackupTransport.TRANSPORT_OK) {
+                        return mPreflight.getExpectedSizeOrErrorCode();
+                    } else {
+                        return mPreflightResult;
+                    }
+                } catch (InterruptedException e) {
+                    return BackupTransport.AGENT_ERROR;
+                }
+            }
+
+            int getBackupResultBlocking() {
+                try {
+                    mBackupLatch.await();
+                    return mBackupResult;
+                } catch (InterruptedException e) {
+                    return BackupTransport.AGENT_ERROR;
+                }
             }
         }
     }
@@ -8550,7 +8626,7 @@
         }
 
         @Override
-        public void operationComplete(int unusedResult) {
+        public void operationComplete(long unusedResult) {
             if (MORE_DEBUG) {
                 Slog.i(TAG, "operationComplete() during restore: target="
                         + mCurrentPackage.packageName
@@ -9635,9 +9711,8 @@
 
         // The completion callback, if any, is invoked on the handler
         if (op != null && op.callback != null) {
-            Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, op.callback);
-            // NB: this cannot distinguish between results > 2 gig
-            msg.arg1 = (result > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) result;
+            Pair<BackupRestoreTask, Long> callbackAndResult = Pair.create(op.callback, result);
+            Message msg = mBackupHandler.obtainMessage(MSG_OP_COMPLETE, callbackAndResult);
             mBackupHandler.sendMessage(msg);
         }
     }
@@ -10129,7 +10204,7 @@
         }
     }
 
-    private static void sendBackupOnResult(IBackupObserver observer, String packageName,
+    private static void sendBackupOnPackageResult(IBackupObserver observer, String packageName,
             int status) {
         if (observer != null) {
             try {
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index bbf881b..e745263 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -54,7 +54,7 @@
 
     public Trampoline(Context context) {
         mContext = context;
-        File dir = new File(Environment.getSecureDataDirectory(), "backup");
+        File dir = new File(Environment.getDataDirectory(), "backup");
         dir.mkdirs();
         mSuppressFile = new File(dir, BACKUP_SUPPRESS_FILENAME);
         mGlobalDisable = SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index a4455e9..91f58c56 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -882,6 +882,11 @@
 
     @Override
     public int checkAudioOperation(int code, int usage, int uid, String packageName) {
+        if (isPackageSuspendedForUser(packageName, uid)) {
+            Log.i(TAG, "Audio disabled for suspended package=" + packageName + " for uid=" + uid);
+            return AppOpsManager.MODE_IGNORED;
+        }
+
         synchronized (this) {
             final int mode = checkRestrictionLocked(code, usage, uid, packageName);
             if (mode != AppOpsManager.MODE_ALLOWED) {
@@ -891,6 +896,15 @@
         return checkOperation(code, uid, packageName);
     }
 
+    private boolean isPackageSuspendedForUser(String pkg, int uid) {
+        try {
+            return AppGlobals.getPackageManager().isPackageSuspendedForUser(
+                    pkg, UserHandle.getUserId(uid));
+        } catch (RemoteException re) {
+            throw new SecurityException("Could not talk to package manager service");
+        }
+    }
+
     private int checkRestrictionLocked(int code, int usage, int uid, String packageName) {
         final SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code);
         if (usageRestrictions != null) {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 499b706..6d0d9e9 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1672,6 +1672,7 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String args[]) {
+      mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
       if (mBluetoothBinder == null) {
         writer.println("Bluetooth Service not connected");
       } else {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 423ef84..6c19c38 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1262,6 +1262,12 @@
         return false;
     }
 
+    public boolean getPowerSaveWhitelistAppInternal(String name) {
+        synchronized (this) {
+            return mPowerSaveWhitelistUserApps.containsKey(name);
+        }
+    }
+
     public String[] getSystemPowerWhitelistExceptIdleInternal() {
         synchronized (this) {
             int size = mPowerSaveWhitelistAppsExceptIdle.size();
@@ -2307,8 +2313,8 @@
                             android.Manifest.permission.DEVICE_POWER, null);
                     do {
                         if (arg.length() < 1 || (arg.charAt(0) != '-'
-                                && arg.charAt(0) != '+')) {
-                            pw.println("Package must be prefixed with + or -: " + arg);
+                                && arg.charAt(0) != '+' && arg.charAt(0) != '=')) {
+                            pw.println("Package must be prefixed with +, -, or =: " + arg);
                             return -1;
                         }
                         char op = arg.charAt(0);
@@ -2319,10 +2325,12 @@
                             } else {
                                 pw.println("Unknown package: " + pkg);
                             }
-                        } else {
+                        } else if (op == '-') {
                             if (removePowerSaveWhitelistAppInternal(pkg)) {
                                 pw.println("Removed: " + pkg);
                             }
+                        } else {
+                            pw.println(getPowerSaveWhitelistAppInternal(pkg));
                         }
                     } while ((arg=shell.getNextArg()) != null);
                 } else {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index d77def6..7770d53 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -666,8 +666,7 @@
                     }
                 }
 
-                buildInputMethodListLocked(
-                        mMethodList, mMethodMap, false /* resetDefaultEnabledIme */);
+                buildInputMethodListLocked(false /* resetDefaultEnabledIme */);
 
                 boolean changed = false;
 
@@ -800,7 +799,7 @@
                 handleMessage(msg);
             }
         }, true /*asyncHandler*/);
-        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mHardKeyboardListener = new HardKeyboardListener();
         mHasFeature = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
@@ -858,7 +857,7 @@
 
         // mSettings should be created before buildInputMethodListLocked
         mSettings = new InputMethodSettings(
-                mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+                mRes, context.getContentResolver(), mMethodMap, mMethodList, userId, !mSystemReady);
 
         // Let the package manager query which are the default imes
         // as they get certain permissions granted by default.
@@ -873,7 +872,7 @@
                             // TODO: We are switching the current user id in the settings
                             // object to query it and then revert the user id. Ideally, we
                             // should call a API in settings with the user id as an argument.
-                            mSettings.setCurrentUserId(userId);
+                            mSettings.switchCurrentUser(userId, true /* copyOnWrite */);
                             List<InputMethodInfo> imes = mSettings
                                     .getEnabledInputMethodListLocked();
                             String[] packageNames = null;
@@ -885,7 +884,9 @@
                                     packageNames[i] = ime.getPackageName();
                                 }
                             }
-                            mSettings.setCurrentUserId(currentUserId);
+                            // If the system is not ready, then we use copy-on-write mode.
+                            final boolean useCopyOnWriteSettings = !mSystemReady;
+                            mSettings.switchCurrentUser(currentUserId, useCopyOnWriteSettings);
                             return packageNames;
                         }
                     }
@@ -906,8 +907,7 @@
         mImeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);
 
         synchronized (mMethodMap) {
-            buildInputMethodListLocked(mMethodList, mMethodMap,
-                    !mImeSelectedOnBoot /* resetDefaultEnabledIme */);
+            buildInputMethodListLocked(!mImeSelectedOnBoot /* resetDefaultEnabledIme */);
         }
         mSettings.enableAllIMEsIfThereIsNoEnabledIME();
 
@@ -987,7 +987,7 @@
             if (DEBUG) {
                 Slog.i(TAG, "Locale has been changed to " + newLocale);
             }
-            buildInputMethodListLocked(mMethodList, mMethodMap, resetDefaultEnabledIme);
+            buildInputMethodListLocked(resetDefaultEnabledIme);
             if (!updateOnlyWhenLocaleChanged) {
                 final String selectedImiId = mSettings.getSelectedInputMethod();
                 if (TextUtils.isEmpty(selectedImiId)) {
@@ -1022,7 +1022,10 @@
 
         // ContentObserver should be registered again when the user is changed
         mSettingsObserver.registerContentObserverLocked(newUserId);
-        mSettings.setCurrentUserId(newUserId);
+
+        // If the system is not ready, then we use copy-on-write settings.
+        final boolean useCopyOnWriteSettings = !mSystemReady;
+        mSettings.switchCurrentUser(newUserId, useCopyOnWriteSettings);
         updateCurrentProfileIds();
         // InputMethodFileManager should be reset when the user is changed
         mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
@@ -1050,8 +1053,8 @@
     }
 
     void updateCurrentProfileIds() {
-        List<UserInfo> profiles =
-                UserManager.get(mContext).getProfiles(mSettings.getCurrentUserId());
+        List<UserInfo> profiles = mContext.getSystemService(UserManager.class)
+                .getProfiles(mSettings.getCurrentUserId());
         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
         for (int i = 0; i < currentProfileIds.length; i++) {
             currentProfileIds[i] = profiles.get(i).id;
@@ -1081,10 +1084,10 @@
             }
             if (!mSystemReady) {
                 mSystemReady = true;
-                mKeyguardManager =
-                        (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-                mNotificationManager = (NotificationManager)
-                        mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+                final int currentUserId = mSettings.getCurrentUserId();
+                mSettings.switchCurrentUser(currentUserId, false /* copyOnWrite */);
+                mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
+                mNotificationManager = mContext.getSystemService(NotificationManager.class);
                 mStatusBar = statusBar;
                 statusBar.setIconVisibility(mSlotIme, false);
                 updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
@@ -1094,8 +1097,7 @@
                     mWindowManagerInternal.setOnHardKeyboardStatusChangeListener(
                             mHardKeyboardListener);
                 }
-                buildInputMethodListLocked(mMethodList, mMethodMap,
-                        !mImeSelectedOnBoot /* resetDefaultEnabledIme */);
+                buildInputMethodListLocked(!mImeSelectedOnBoot /* resetDefaultEnabledIme */);
                 if (!mImeSelectedOnBoot) {
                     Slog.w(TAG, "Reset the default IME as \"Resource\" is ready here.");
                     resetStateIfCurrentLocaleChangedLocked();
@@ -2601,8 +2603,7 @@
                         mFileManager.addInputMethodSubtypes(imi, subtypes);
                         final long ident = Binder.clearCallingIdentity();
                         try {
-                            buildInputMethodListLocked(mMethodList, mMethodMap,
-                                    false /* resetDefaultEnabledIme */);
+                            buildInputMethodListLocked(false /* resetDefaultEnabledIme */);
                         } finally {
                             Binder.restoreCallingIdentity(ident);
                         }
@@ -2957,14 +2958,13 @@
         return false;
     }
 
-    void buildInputMethodListLocked(ArrayList<InputMethodInfo> list,
-            HashMap<String, InputMethodInfo> map, boolean resetDefaultEnabledIme) {
+    void buildInputMethodListLocked(boolean resetDefaultEnabledIme) {
         if (DEBUG) {
             Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
                     + " \n ------ caller=" + Debug.getCallers(10));
         }
-        list.clear();
-        map.clear();
+        mMethodList.clear();
+        mMethodMap.clear();
 
         // Use for queryIntentServicesAsUser
         final PackageManager pm = mContext.getPackageManager();
@@ -2992,9 +2992,9 @@
 
             try {
                 InputMethodInfo p = new InputMethodInfo(mContext, ri, additionalSubtypes);
-                list.add(p);
+                mMethodList.add(p);
                 final String id = p.getId();
-                map.put(id, p);
+                mMethodMap.put(id, p);
 
                 if (DEBUG) {
                     Slog.d(TAG, "Found an input method " + p);
@@ -3004,10 +3004,30 @@
             }
         }
 
+        // TODO: The following code should find better place to live.
+        if (!resetDefaultEnabledIme) {
+            boolean enabledImeFound = false;
+            final List<InputMethodInfo> enabledImes = mSettings.getEnabledInputMethodListLocked();
+            final int N = enabledImes.size();
+            for (int i = 0; i < N; ++i) {
+                final InputMethodInfo imi = enabledImes.get(i);
+                if (mMethodList.contains(imi)) {
+                    enabledImeFound = true;
+                    break;
+                }
+            }
+            if (!enabledImeFound) {
+                Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
+                resetDefaultEnabledIme = true;
+                resetSelectedInputMethodAndSubtypeLocked("");
+            }
+        }
+
         if (resetDefaultEnabledIme) {
             final ArrayList<InputMethodInfo> defaultEnabledIme =
-                    InputMethodUtils.getDefaultEnabledImes(mContext, mSystemReady, list);
-            for (int i = 0; i < defaultEnabledIme.size(); ++i) {
+                    InputMethodUtils.getDefaultEnabledImes(mContext, mSystemReady, mMethodList);
+            final int N = defaultEnabledIme.size();
+            for (int i = 0; i < N; ++i) {
                 final InputMethodInfo imi =  defaultEnabledIme.get(i);
                 if (DEBUG) {
                     Slog.d(TAG, "--- enable ime = " + imi);
@@ -3018,7 +3038,7 @@
 
         final String defaultImiId = mSettings.getSelectedInputMethod();
         if (!TextUtils.isEmpty(defaultImiId)) {
-            if (!map.containsKey(defaultImiId)) {
+            if (!mMethodMap.containsKey(defaultImiId)) {
                 Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
                 if (chooseNewDefaultIMELocked()) {
                     updateInputMethodsFromSettingsLocked(true);
@@ -3137,8 +3157,7 @@
 
             mDialogBuilder.setIcon(dialogIcon);
 
-            final LayoutInflater inflater = (LayoutInflater) dialogContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
+            final LayoutInflater inflater = dialogContext.getSystemService(LayoutInflater.class);
             final View tv = inflater.inflate(
                     com.android.internal.R.layout.input_method_switch_dialog_title, null);
             mDialogBuilder.setCustomTitle(tv);
@@ -3222,7 +3241,7 @@
             mTextViewResourceId = textViewResourceId;
             mItemsList = itemsList;
             mCheckedItem = checkedItem;
-            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            mInflater = context.getSystemService(LayoutInflater.class);
         }
 
         @Override
@@ -3370,16 +3389,7 @@
             }
         }
 
-        // Workaround.
-        // ASEC is not ready in the IMMS constructor. Accordingly, forward-locked
-        // IMEs are not recognized and considered uninstalled.
-        // Actually, we can't move everything after SystemReady because
-        // IMMS needs to run in the encryption lock screen. So, we just skip changing
-        // the default IME here and try cheking the default IME again in systemReady().
-        // TODO: Do nothing before system ready and implement a separated logic for
-        // the encryption lock screen.
-        // TODO: ASEC should be ready before IMMS is instantiated.
-        if (mSystemReady && !setSubtypeOnly) {
+        if (!setSubtypeOnly) {
             // Set InputMethod here
             mSettings.putSelectedInputMethod(imi != null ? imi.getId() : "");
         }
@@ -3860,6 +3870,8 @@
             p.println("  mSettingsObserver=" + mSettingsObserver);
             p.println("  mSwitchingController:");
             mSwitchingController.dump(p);
+            p.println("  mSettings:");
+            mSettings.dumpLocked(p, "    ");
         }
 
         p.println(" ");
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ecba0a4..c318140 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.app.ActivityManagerNative;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -34,6 +35,7 @@
 import android.content.res.Resources;
 
 import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE;
+import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.Context.USER_SERVICE;
 import static android.Manifest.permission.READ_CONTACTS;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
@@ -62,6 +64,10 @@
 import com.android.internal.widget.VerifyCredentialResponse;
 import com.android.server.LockSettingsStorage.CredentialHash;
 
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
 import java.util.Arrays;
 import java.util.List;
 
@@ -120,7 +126,7 @@
         @Override
         public void onBootPhase(int phase) {
             if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
-                mLockSettingsService.maybeShowEncryptionNotification(UserHandle.ALL);
+                mLockSettingsService.maybeShowEncryptionNotifications();
             } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
                 // TODO
             }
@@ -172,22 +178,48 @@
      * If the account is credential-encrypted, show notification requesting the user to unlock
      * the device.
      */
-    private void maybeShowEncryptionNotification(UserHandle userHandle) {
-        if (UserHandle.ALL.equals(userHandle)) {
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (int i = 0; i < users.size(); i++) {
-                UserHandle user = users.get(i).getUserHandle();
-                if (!mUserManager.isUserUnlocked(user)) {
-                    showEncryptionNotification(user);
+    private void maybeShowEncryptionNotifications() {
+        final List<UserInfo> users = mUserManager.getUsers();
+        for (int i = 0; i < users.size(); i++) {
+            UserInfo user = users.get(i);
+            UserHandle userHandle = user.getUserHandle();
+            if (!mUserManager.isUserUnlocked(userHandle)) {
+                if (!user.isManagedProfile()) {
+                    showEncryptionNotification(userHandle);
+                } else {
+                    UserInfo parent = mUserManager.getProfileParent(user.id);
+                    if (parent != null && mUserManager.isUserUnlocked(parent.getUserHandle())) {
+                        // Only show notifications for managed profiles once their parent
+                        // user is unlocked.
+                        showEncryptionNotificationForProfile(userHandle);
+                    }
                 }
             }
-        } else if (!mUserManager.isUserUnlocked(userHandle)){
-            showEncryptionNotification(userHandle);
         }
     }
 
+    private void showEncryptionNotificationForProfile(UserHandle user) {
+        Resources r = mContext.getResources();
+        CharSequence title = r.getText(
+                com.android.internal.R.string.user_encrypted_title);
+        CharSequence message = r.getText(
+                com.android.internal.R.string.profile_encrypted_message);
+        CharSequence detail = r.getText(
+                com.android.internal.R.string.profile_encrypted_detail);
+
+        final KeyguardManager km = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
+        final Intent unlockIntent = km.createConfirmDeviceCredentialIntent(null, null, user.getIdentifier());
+        if (unlockIntent == null) {
+            return;
+        }
+        unlockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+
+        showEncryptionNotification(user, title, message, detail, intent);
+    }
+
     private void showEncryptionNotification(UserHandle user) {
-        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
         Resources r = mContext.getResources();
         CharSequence title = r.getText(
                 com.android.internal.R.string.user_encrypted_title);
@@ -199,6 +231,12 @@
         PendingIntent intent = PendingIntent.getBroadcast(mContext, 0, ACTION_NULL,
                 PendingIntent.FLAG_UPDATE_CURRENT);
 
+        showEncryptionNotification(user, title, message, detail, intent);
+    }
+
+    private void showEncryptionNotification(UserHandle user, CharSequence title, CharSequence message,
+            CharSequence detail, PendingIntent intent) {
+        if (DEBUG) Slog.v(TAG, "showing encryption notification, user: " + user.getIdentifier());
         Notification notification = new Notification.Builder(mContext)
                 .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
                 .setWhen(0)
@@ -226,8 +264,21 @@
         hideEncryptionNotification(new UserHandle(userId));
     }
 
-    public void onUnlockUser(int userHandle) {
-        hideEncryptionNotification(new UserHandle(userHandle));
+    public void onUnlockUser(int userId) {
+        hideEncryptionNotification(new UserHandle(userId));
+
+        // Now we have unlocked the parent user we should show notifications
+        // about any profiles that exist.
+        List<UserInfo> profiles = mUserManager.getProfiles(userId);
+        for (int i = 0; i < profiles.size(); i++) {
+            UserInfo profile = profiles.get(i);
+            if (profile.isManagedProfile()) {
+                UserHandle userHandle = profile.getUserHandle();
+                if (!mUserManager.isUserUnlocked(userHandle)) {
+                    showEncryptionNotificationForProfile(userHandle);
+                }
+            }
+        }
     }
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -510,9 +561,9 @@
         }
     }
 
-    private void unlockUser(int userId, byte[] token) {
+    private void unlockUser(int userId, byte[] token, byte[] secret) {
         try {
-            ActivityManagerNative.getDefault().unlockUser(userId, token);
+            ActivityManagerNative.getDefault().unlockUser(userId, token, secret);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
@@ -560,6 +611,7 @@
             getGateKeeperService().clearSecureUserId(userId);
             mStorage.writePatternHash(null, userId);
             setKeystorePassword(null, userId);
+            clearUserKeyProtection(userId);
             return;
         }
 
@@ -573,6 +625,7 @@
         byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, pattern, userId);
         if (enrolledHandle != null) {
             mStorage.writePatternHash(enrolledHandle, userId);
+            setUserKeyProtection(userId, pattern, verifyPattern(pattern, 0, userId));
         } else {
             throw new RemoteException("Failed to enroll pattern");
         }
@@ -588,6 +641,7 @@
             getGateKeeperService().clearSecureUserId(userId);
             mStorage.writePasswordHash(null, userId);
             setKeystorePassword(null, userId);
+            clearUserKeyProtection(userId);
             return;
         }
 
@@ -601,6 +655,7 @@
         byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, password, userId);
         if (enrolledHandle != null) {
             mStorage.writePasswordHash(enrolledHandle, userId);
+            setUserKeyProtection(userId, password, verifyPassword(password, 0, userId));
         } else {
             throw new RemoteException("Failed to enroll password");
         }
@@ -633,6 +688,48 @@
         return hash;
     }
 
+    private void setUserKeyProtection(int userId, String credential, VerifyCredentialResponse vcr)
+            throws RemoteException {
+        if (vcr == null) {
+            throw new RemoteException("Null response verifying a credential we just set");
+        }
+        if (vcr.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+            throw new RemoteException("Non-OK response verifying a credential we just set: "
+                + vcr.getResponseCode());
+        }
+        byte[] token = vcr.getPayload();
+        if (token == null) {
+            throw new RemoteException("Empty payload verifying a credential we just set");
+        }
+        changeUserKey(userId, token, secretFromCredential(credential));
+    }
+
+    private void clearUserKeyProtection(int userId) throws RemoteException {
+        changeUserKey(userId, null, null);
+    }
+
+    private static byte[] secretFromCredential(String credential) throws RemoteException {
+        try {
+            MessageDigest digest = MessageDigest.getInstance("SHA-512");
+            // Personalize the hash
+            byte[] personalization = "Android FBE credential hash"
+                    .getBytes(StandardCharsets.UTF_8);
+            // Pad it to the block size of the hash function
+            personalization = Arrays.copyOf(personalization, 128);
+            digest.update(personalization);
+            digest.update(credential.getBytes(StandardCharsets.UTF_8));
+            return digest.digest();
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("NoSuchAlgorithmException for SHA-512");
+        }
+    }
+
+    private void changeUserKey(int userId, byte[] token, byte[] secret)
+            throws RemoteException {
+        final UserInfo userInfo = UserManager.get(mContext).getUserInfo(userId);
+        getMountService().changeUserKey(userId, userInfo.serialNumber, token, null, secret);
+    }
+
     @Override
     public VerifyCredentialResponse checkPattern(String pattern, int userId) throws RemoteException {
         return doVerifyPattern(pattern, false, 0, userId);
@@ -742,11 +839,11 @@
             if (Arrays.equals(hash, storedHash.hash)) {
                 unlockKeystore(credentialUtil.adjustForKeystore(credential), userId);
 
-                // TODO: pass through a meaningful token from gatekeeper to
-                // unlock credential keys; for now pass through a stub value to
-                // indicate that we came from a user challenge.
-                final byte[] token = String.valueOf(userId).getBytes();
-                unlockUser(userId, token);
+                // Users with legacy credentials don't have credential-backed
+                // FBE keys, so just pass through a fake token/secret
+                Slog.i(TAG, "Unlocking user with fake token: " + userId);
+                final byte[] fakeToken = String.valueOf(userId).getBytes();
+                unlockUser(userId, fakeToken, fakeToken);
 
                 // migrate credential to GateKeeper
                 credentialUtil.setCredential(credential, null, userId);
@@ -786,11 +883,9 @@
             // credential has matched
             unlockKeystore(credential, userId);
 
-            // TODO: pass through a meaningful token from gatekeeper to
-            // unlock credential keys; for now pass through a stub value to
-            // indicate that we came from a user challenge.
-            final byte[] token = String.valueOf(userId).getBytes();
-            unlockUser(userId, token);
+            Slog.i(TAG, "Unlocking user " + userId +
+                " with token length " + response.getPayload().length);
+            unlockUser(userId, response.getPayload(), secretFromCredential(credential));
 
             UserInfo info = UserManager.get(mContext).getUserInfo(userId);
             if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 5120e1b..53923ba 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -844,6 +844,7 @@
             // user directories are locked or unlocked based on the current
             // emulation status.
             final boolean initLocked = StorageManager.isEmulatedFileBasedEncryptionEnabled();
+            Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked);
             final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
             for (UserInfo user : users) {
                 try {
@@ -851,7 +852,7 @@
                         mCryptConnector.execute("cryptfs", "lock_user_key", user.id);
                     } else {
                         mCryptConnector.execute("cryptfs", "unlock_user_key", user.id,
-                                user.serialNumber, "!");
+                                user.serialNumber, "!", "!");
                     }
                 } catch (NativeDaemonConnectorException e) {
                     Slog.w(TAG, "Failed to init vold", e);
@@ -1473,7 +1474,7 @@
         }
 
         mSettingsFile = new AtomicFile(
-                new File(Environment.getSystemSecureDirectory(), "storage.xml"));
+                new File(Environment.getDataSystemDirectory(), "storage.xml"));
 
         synchronized (mLock) {
             readSettingsLocked();
@@ -2742,8 +2743,30 @@
         }
     }
 
+    private SensitiveArg encodeBytes(byte[] bytes) {
+        if (ArrayUtils.isEmpty(bytes)) {
+            return new SensitiveArg("!");
+        } else {
+            return new SensitiveArg(HexDump.toHexString(bytes));
+        }
+    }
+
     @Override
-    public void unlockUserKey(int userId, int serialNumber, byte[] token) {
+    public void changeUserKey(int userId, int serialNumber,
+            byte[] token, byte[] oldSecret, byte[] newSecret) {
+        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
+        waitForReady();
+
+        try {
+            mCryptConnector.execute("cryptfs", "change_user_key", userId, serialNumber,
+                encodeBytes(token), encodeBytes(oldSecret), encodeBytes(newSecret));
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
         enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
         waitForReady();
 
@@ -2753,16 +2776,9 @@
             throw new IllegalStateException("Token required to unlock secure user " + userId);
         }
 
-        final String encodedToken;
-        if (ArrayUtils.isEmpty(token)) {
-            encodedToken = "!";
-        } else {
-            encodedToken = HexDump.toHexString(token);
-        }
-
         try {
             mCryptConnector.execute("cryptfs", "unlock_user_key", userId, serialNumber,
-                    new SensitiveArg(encodedToken));
+                    encodeBytes(token), encodeBytes(secret));
         } catch (NativeDaemonConnectorException e) {
             throw e.rethrowAsParcelableException();
         }
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 95f5734..799d0bd 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -2086,7 +2086,7 @@
             final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT);
             if (DBG) {
                 Slog.d(TAG, "oldRule = " + oldUidFirewallRule
-                        + ", newRule=" + rule + " for uid=" + uid);
+                        + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain);
             }
             if (oldUidFirewallRule == rule) {
                 if (DBG) Slog.d(TAG, "!!!!! Skipping change");
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index b984e19..879bb6f 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -234,12 +234,24 @@
             // safety as scores should never be compared across apps; in practice, Settings should
             // only be allowing valid apps to be set as scorers, so failure here should be rare.
             clearInternal();
+            // Get the scorer that is about to be replaced, if any, so we can notify it directly.
+            NetworkScorerAppData prevScorer = NetworkScorerAppManager.getActiveScorer(mContext);
             boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName);
-            if (result) {
+            if (result) { // new scorer successfully set
                 registerPackageReceiverIfNeeded();
                 Intent intent = new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED);
-                intent.putExtra(NetworkScoreManager.EXTRA_NEW_SCORER, packageName);
-                mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+                if (prevScorer != null) { // Directly notify the old scorer.
+                    intent.setPackage(prevScorer.mPackageName);
+                    // TODO: Need to update when we support per-user scorers. http://b/23422763
+                    mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+                }
+
+                if (packageName != null) { // Then notify the new scorer
+                    intent.putExtra(NetworkScoreManager.EXTRA_NEW_SCORER, packageName);
+                    intent.setPackage(packageName);
+                    // TODO: Need to update when we support per-user scorers. http://b/23422763
+                    mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+                }
             }
             return result;
         } finally {
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index 6062137..383e25a 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.annotation.Nullable;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -32,13 +33,16 @@
 import android.os.IBinder;
 import android.os.UserHandle;
 import android.util.Log;
+import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Find the best Service, and bind to it.
@@ -64,17 +68,21 @@
     private final Runnable mNewServiceWork;
     private final Handler mHandler;
 
-    private Object mLock = new Object();
+    private final Object mLock = new Object();
 
-    // all fields below synchronized on mLock
-    private IBinder mBinder;   // connected service
-    private String mPackageName;  // current best package
-    private int mVersion = Integer.MIN_VALUE;  // current best version
-    /**
-     * Whether the currently-connected service is multiuser-aware. This can change at run-time
-     * when switching from one version of a service to another.
-     */
-    private boolean mIsMultiuser = false;
+    @GuardedBy("mLock")
+    private int mCurrentUserId = UserHandle.USER_SYSTEM;
+
+    @GuardedBy("mLock")
+    private IBinder mBoundService;
+    @GuardedBy("mLock")
+    private ComponentName mBoundComponent;
+    @GuardedBy("mLock")
+    private String mBoundPackageName;
+    @GuardedBy("mLock")
+    private int mBoundVersion = Integer.MIN_VALUE;
+    @GuardedBy("mLock")
+    private int mBoundUserId = UserHandle.USER_NULL;
 
     public static ArrayList<HashSet<Signature>> getSignatureSets(Context context,
             List<String> initialPackageNames) {
@@ -84,7 +92,8 @@
             String pkg = initialPackageNames.get(i);
             try {
                 HashSet<Signature> set = new HashSet<Signature>();
-                Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES).signatures;
+                Signature[] sigs = pm.getPackageInfo(pkg, PackageManager.MATCH_SYSTEM_ONLY
+                        | PackageManager.GET_SIGNATURES).signatures;
                 set.addAll(Arrays.asList(sigs));
                 sigSets.add(set);
             } catch (NameNotFoundException e) {
@@ -108,7 +117,7 @@
 
         // Whether to enable service overlay.
         boolean enableOverlay = resources.getBoolean(overlaySwitchResId);
-        ArrayList<String>  initialPackageNames = new ArrayList<String>();
+        ArrayList<String> initialPackageNames = new ArrayList<String>();
         if (enableOverlay) {
             // A list of package names used to create the signatures.
             String[] pkgs = resources.getStringArray(initialPackageNamesResId);
@@ -126,20 +135,32 @@
         mSignatureSets = getSignatureSets(context, initialPackageNames);
     }
 
+    /**
+     * Start this watcher, including binding to the current best match and
+     * re-binding to any better matches down the road.
+     * <p>
+     * Note that if there are no matching encryption-aware services, we may not
+     * bind to a real service until after the current user is unlocked.
+     */
     public boolean start() {
         synchronized (mLock) {
-            if (!bindBestPackageLocked(mServicePackageName)) return false;
+            bindBestPackageLocked(mServicePackageName, false);
         }
 
         // listen for user change
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
         mContext.registerReceiverAsUser(new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
+                final String action = intent.getAction();
+                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
+                        UserHandle.USER_NULL);
                 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
-                    switchUser();
+                    switchUser(userId);
+                } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+                    unlockUser(userId);
                 }
             }
         }, UserHandle.ALL, intentFilter, null, mHandler);
@@ -153,30 +174,36 @@
     }
 
     /**
-     * Searches and binds to the best package, or do nothing
-     * if the best package is already bound.
-     * Only checks the named package, or checks all packages if it
-     * is null.
-     * Return true if a new package was found to bind to.
+     * Searches and binds to the best package, or do nothing if the best package
+     * is already bound, unless force rebinding is requested.
+     *
+     * @param justCheckThisPackage Only consider this package, or consider all
+     *            packages if it is {@code null}.
+     * @param forceRebind Force a rebinding to the best package if it's already
+     *            bound.
+     * @return {@code true} if a valid package was found to bind to.
      */
-    private boolean bindBestPackageLocked(String justCheckThisPackage) {
+    private boolean bindBestPackageLocked(String justCheckThisPackage, boolean forceRebind) {
         Intent intent = new Intent(mAction);
         if (justCheckThisPackage != null) {
             intent.setPackage(justCheckThisPackage);
         }
-        List<ResolveInfo> rInfos = mPm.queryIntentServicesAsUser(intent,
-                PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM);
+        final List<ResolveInfo> rInfos = mPm.queryIntentServicesAsUser(intent,
+                PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+                mCurrentUserId);
         int bestVersion = Integer.MIN_VALUE;
-        String bestPackage = null;
+        ComponentName bestComponent = null;
         boolean bestIsMultiuser = false;
         if (rInfos != null) {
             for (ResolveInfo rInfo : rInfos) {
-                String packageName = rInfo.serviceInfo.packageName;
+                final ComponentName component = rInfo.serviceInfo.getComponentName();
+                final String packageName = component.getPackageName();
 
                 // check signature
                 try {
                     PackageInfo pInfo;
-                    pInfo = mPm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+                    pInfo = mPm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES
+                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
                     if (!isSignatureMatch(pInfo.signatures)) {
                         Log.w(mTag, packageName + " resolves service " + mAction
                                 + ", but has wrong signature, ignoring");
@@ -196,9 +223,9 @@
                     isMultiuser = rInfo.serviceInfo.metaData.getBoolean(EXTRA_SERVICE_IS_MULTIUSER);
                 }
 
-                if (version > mVersion) {
+                if (version > bestVersion) {
                     bestVersion = version;
-                    bestPackage = packageName;
+                    bestComponent = component;
                     bestIsMultiuser = isMultiuser;
                 }
             }
@@ -207,42 +234,53 @@
                 Log.d(mTag, String.format("bindBestPackage for %s : %s found %d, %s", mAction,
                         (justCheckThisPackage == null ? ""
                                 : "(" + justCheckThisPackage + ") "), rInfos.size(),
-                        (bestPackage == null ? "no new best package"
-                                : "new best package: " + bestPackage)));
+                        (bestComponent == null ? "no new best component"
+                                : "new best component: " + bestComponent)));
             }
         } else {
             if (D) Log.d(mTag, "Unable to query intent services for action: " + mAction);
         }
-        if (bestPackage != null) {
-            bindToPackageLocked(bestPackage, bestVersion, bestIsMultiuser);
-            return true;
+
+        if (bestComponent == null) {
+            Slog.w(mTag, "Odd, no component found for service " + mAction);
+            unbindLocked();
+            return false;
         }
-        return false;
+
+        final int userId = bestIsMultiuser ? UserHandle.USER_SYSTEM : mCurrentUserId;
+        final boolean alreadyBound = Objects.equals(bestComponent, mBoundComponent)
+                && bestVersion == mBoundVersion && userId == mBoundUserId;
+        if (forceRebind || !alreadyBound) {
+            unbindLocked();
+            bindToPackageLocked(bestComponent, bestVersion, userId);
+        }
+        return true;
     }
 
     private void unbindLocked() {
-        String pkg;
-        pkg = mPackageName;
-        mPackageName = null;
-        mVersion = Integer.MIN_VALUE;
-        mIsMultiuser = false;
-        if (pkg != null) {
-            if (D) Log.d(mTag, "unbinding " + pkg);
+        ComponentName component;
+        component = mBoundComponent;
+        mBoundComponent = null;
+        mBoundPackageName = null;
+        mBoundVersion = Integer.MIN_VALUE;
+        mBoundUserId = UserHandle.USER_NULL;
+        if (component != null) {
+            if (D) Log.d(mTag, "unbinding " + component);
             mContext.unbindService(this);
         }
     }
 
-    private void bindToPackageLocked(String packageName, int version, boolean isMultiuser) {
-        unbindLocked();
+    private void bindToPackageLocked(ComponentName component, int version, int userId) {
         Intent intent = new Intent(mAction);
-        intent.setPackage(packageName);
-        mPackageName = packageName;
-        mVersion = version;
-        mIsMultiuser = isMultiuser;
-        if (D) Log.d(mTag, "binding " + packageName + " (version " + version + ") ("
-                + (isMultiuser ? "multi" : "single") + "-user)");
-        mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
-                | Context.BIND_NOT_VISIBLE, mIsMultiuser ? UserHandle.SYSTEM : UserHandle.CURRENT);
+        intent.setComponent(component);
+        mBoundComponent = component;
+        mBoundPackageName = component.getPackageName();
+        mBoundVersion = version;
+        mBoundUserId = userId;
+        if (D) Log.d(mTag, "binding " + component + " (v" + version + ") (u" + userId + ")");
+        mContext.bindServiceAsUser(intent, this,
+                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND | Context.BIND_NOT_VISIBLE,
+                new UserHandle(userId));
     }
 
     public static boolean isSignatureMatch(Signature[] signatures,
@@ -275,106 +313,92 @@
         @Override
         public void onPackageUpdateFinished(String packageName, int uid) {
             synchronized (mLock) {
-                if (packageName.equals(mPackageName)) {
-                    // package updated, make sure to rebind
-                    unbindLocked();
-                }
-                // Need to check all packages because this method is also called when a
-                // system app is uninstalled and the stock version in reinstalled.
-                bindBestPackageLocked(null);
+                final boolean forceRebind = Objects.equals(packageName, mBoundPackageName);
+                bindBestPackageLocked(null, forceRebind);
             }
         }
 
         @Override
         public void onPackageAdded(String packageName, int uid) {
             synchronized (mLock) {
-                if (packageName.equals(mPackageName)) {
-                    // package updated, make sure to rebind
-                    unbindLocked();
-                }
-                // check the new package is case it is better
-                bindBestPackageLocked(null);
+                final boolean forceRebind = Objects.equals(packageName, mBoundPackageName);
+                bindBestPackageLocked(null, forceRebind);
             }
         }
 
         @Override
         public void onPackageRemoved(String packageName, int uid) {
             synchronized (mLock) {
-                if (packageName.equals(mPackageName)) {
-                    unbindLocked();
-                    // the currently bound package was removed,
-                    // need to search for a new package
-                    bindBestPackageLocked(null);
-                }
+                final boolean forceRebind = Objects.equals(packageName, mBoundPackageName);
+                bindBestPackageLocked(null, forceRebind);
             }
         }
 
         @Override
         public boolean onPackageChanged(String packageName, int uid, String[] components) {
             synchronized (mLock) {
-                if (packageName.equals(mPackageName)) {
-                    // service enabled or disabled, make sure to rebind
-                    unbindLocked();
-                }
-                // the service might be disabled, need to search for a new
-                // package
-                bindBestPackageLocked(null);
+                final boolean forceRebind = Objects.equals(packageName, mBoundPackageName);
+                bindBestPackageLocked(null, forceRebind);
             }
             return super.onPackageChanged(packageName, uid, components);
         }
     };
 
     @Override
-    public void onServiceConnected(ComponentName name, IBinder binder) {
+    public void onServiceConnected(ComponentName component, IBinder binder) {
         synchronized (mLock) {
-            String packageName = name.getPackageName();
-            if (packageName.equals(mPackageName)) {
-                if (D) Log.d(mTag, packageName + " connected");
-                mBinder = binder;
+            if (component.equals(mBoundComponent)) {
+                if (D) Log.d(mTag, component + " connected");
+                mBoundService = binder;
                 if (mHandler !=null && mNewServiceWork != null) {
                     mHandler.post(mNewServiceWork);
                 }
             } else {
-                Log.w(mTag, "unexpected onServiceConnected: " + packageName);
+                Log.w(mTag, "unexpected onServiceConnected: " + component);
             }
         }
     }
 
     @Override
-    public void onServiceDisconnected(ComponentName name) {
+    public void onServiceDisconnected(ComponentName component) {
         synchronized (mLock) {
-            String packageName = name.getPackageName();
-            if (D) Log.d(mTag, packageName + " disconnected");
+            if (D) Log.d(mTag, component + " disconnected");
 
-            if (packageName.equals(mPackageName)) {
-                mBinder = null;
+            if (component.equals(mBoundComponent)) {
+                mBoundService = null;
             }
         }
     }
 
-    public String getBestPackageName() {
+    public @Nullable String getBestPackageName() {
         synchronized (mLock) {
-            return mPackageName;
+            return mBoundPackageName;
         }
     }
 
     public int getBestVersion() {
         synchronized (mLock) {
-            return mVersion;
+            return mBoundVersion;
         }
     }
 
-    public IBinder getBinder() {
+    public @Nullable IBinder getBinder() {
         synchronized (mLock) {
-            return mBinder;
+            return mBoundService;
         }
     }
 
-    public void switchUser() {
+    public void switchUser(int userId) {
         synchronized (mLock) {
-            if (!mIsMultiuser) {
-                unbindLocked();
-                bindBestPackageLocked(mServicePackageName);
+            mCurrentUserId = userId;
+            bindBestPackageLocked(mServicePackageName, false);
+        }
+    }
+
+    public void unlockUser(int userId) {
+        synchronized (mLock) {
+            if (userId == mCurrentUserId) {
+                bindBestPackageLocked(mServicePackageName, false);
             }
         }
     }
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 5aba22d..7bdd3e2 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -342,6 +342,7 @@
 
                 } else if ("feature".equals(name) && allowFeatures) {
                     String fname = parser.getAttributeValue(null, "name");
+                    int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
                     boolean allowed;
                     if (!lowRam) {
                         allowed = true;
@@ -353,7 +354,7 @@
                         Slog.w(TAG, "<feature> without name in " + permFile + " at "
                                 + parser.getPositionDescription());
                     } else if (allowed) {
-                        addFeature(fname);
+                        addFeature(fname, fversion);
                     }
                     XmlUtils.skipCurrentTag(parser);
                     continue;
@@ -445,8 +446,8 @@
         // Some devices can be field-converted to FBE, so offer to splice in
         // those features if not already defined by the static config
         if (StorageManager.isNativeFileBasedEncryptionEnabled()) {
-            addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION);
-            addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS);
+            addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0);
+            addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0);
         }
 
         for (String featureName : mUnavailableFeatures) {
@@ -454,17 +455,21 @@
         }
     }
 
-    private void addFeature(String featureName) {
-        if (!mAvailableFeatures.containsKey(featureName)) {
-            final FeatureInfo fi = new FeatureInfo();
-            fi.name = featureName;
-            mAvailableFeatures.put(featureName, fi);
+    private void addFeature(String name, int version) {
+        FeatureInfo fi = mAvailableFeatures.get(name);
+        if (fi == null) {
+            fi = new FeatureInfo();
+            fi.name = name;
+            fi.version = version;
+            mAvailableFeatures.put(name, fi);
+        } else {
+            fi.version = Math.max(fi.version, version);
         }
     }
 
-    private void removeFeature(String featureName) {
-        if (mAvailableFeatures.remove(featureName) != null) {
-            Slog.d(TAG, "Removed unavailable feature " + featureName);
+    private void removeFeature(String name) {
+        if (mAvailableFeatures.remove(name) != null) {
+            Slog.d(TAG, "Removed unavailable feature " + name);
         }
     }
 
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 2683be6..ca1e371 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3809,7 +3809,7 @@
     }
 
     private static String getDatabaseName(int userId) {
-        File systemDir = Environment.getSystemSecureDirectory();
+        File systemDir = Environment.getDataSystemDirectory();
         File databaseFile = new File(Environment.getUserSystemDirectory(userId), DATABASE_NAME);
         if (userId == 0) {
             // Migrate old file, if it exists, to the new location.
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index bef6f0a..4f0d4d9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -62,7 +62,7 @@
     static final boolean DEBUG_LRU = DEBUG_ALL || false;
     static final boolean DEBUG_MU = DEBUG_ALL || false;
     static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
-    static final boolean DEBUG_PAUSE = DEBUG_ALL || true;
+    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
     static final boolean DEBUG_POWER = DEBUG_ALL || false;
     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
     static final boolean DEBUG_PROCESS_OBSERVERS = DEBUG_ALL || false;
@@ -77,7 +77,7 @@
     static final boolean DEBUG_SERVICE = DEBUG_ALL || false;
     static final boolean DEBUG_SERVICE_EXECUTING = DEBUG_ALL || false;
     static final boolean DEBUG_STACK = DEBUG_ALL || false;
-    static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || true;
+    static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
     static final boolean DEBUG_TASKS = DEBUG_ALL || false;
     static final boolean DEBUG_THUMBNAILS = DEBUG_ALL || false;
@@ -85,7 +85,7 @@
     static final boolean DEBUG_UID_OBSERVERS = DEBUG_ALL || false;
     static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
     static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
-    static final boolean DEBUG_VISIBILITY = DEBUG_ALL || true;
+    static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
     static final boolean DEBUG_VISIBLE_BEHIND = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_USAGE_STATS = DEBUG_ALL || false;
     static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5125133..c7f7378 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -499,6 +499,9 @@
     private static final int PERSISTENT_MASK =
             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
 
+    // Intent sent when remote bugreport collection has been completed
+    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
+            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
 
     // Delay to disable app launch boost
     static final int APP_BOOST_MESSAGE_DELAY = 3000;
@@ -1451,6 +1454,7 @@
     static final int VR_MODE_CHANGE_MSG = 63;
     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
+    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1979,6 +1983,20 @@
                 }
                 break;
             }
+            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
+                        try {
+                            // Make a one-way callback to the listener
+                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
+                        } catch (RemoteException e){
+                            // Handled by the RemoteCallbackList
+                        }
+                    }
+                    mTaskStackListeners.finishBroadcast();
+                }
+                break;
+            }
             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
                 final int uid = msg.arg1;
                 final byte[] firstPacket = (byte[]) msg.obj;
@@ -2836,31 +2854,39 @@
 
     @Override
     public void setFocusedStack(int stackId) {
+        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
-        synchronized (ActivityManagerService.this) {
-            ActivityStack stack = mStackSupervisor.getStack(stackId);
-            if (stack != null) {
-                ActivityRecord r = stack.topRunningActivityLocked();
-                if (r != null) {
-                    setFocusedActivityLocked(r, "setFocusedStack");
+        final long callingId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                final ActivityStack stack = mStackSupervisor.getStack(stackId);
+                if (stack == null) {
+                    return;
+                }
+                final ActivityRecord r = stack.topRunningActivityLocked();
+                if (setFocusedActivityLocked(r, "setFocusedStack")) {
                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
                 }
             }
+        } finally {
+            Binder.restoreCallingIdentity(callingId);
         }
     }
 
     @Override
     public void setFocusedTask(int taskId) {
+        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
-        long callingId = Binder.clearCallingIdentity();
+        final long callingId = Binder.clearCallingIdentity();
         try {
-            synchronized (ActivityManagerService.this) {
-                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
-                if (task != null) {
-                    final ActivityRecord r = task.topRunningActivityLocked();
-                    if (setFocusedActivityLocked(r, "setFocusedTask")) {
-                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
-                    }
+            synchronized (this) {
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                if (task == null) {
+                    return;
+                }
+                final ActivityRecord r = task.topRunningActivityLocked();
+                if (setFocusedActivityLocked(r, "setFocusedTask")) {
+                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
                 }
             }
         } finally {
@@ -6404,6 +6430,9 @@
                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
                     updateSleepIfNeededLocked();
+
+                    // Some stack visibility might change (e.g. docked stack)
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                 }
             }
         } finally {
@@ -7161,8 +7190,8 @@
                 final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
                         ? mDefaultPinnedStackBounds : null;
 
-                mStackSupervisor.moveActivityToStackLocked(
-                        r, PINNED_STACK_ID, "enterPictureInPicture", bounds);
+                mStackSupervisor.moveActivityToPinnedStackLocked(
+                        r, "enterPictureInPicture", bounds);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -9186,11 +9215,35 @@
     }
 
     @Override
-    public boolean removeTask(int taskId) {
+    public void removeStack(int stackId) {
+        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
+        if (stackId == HOME_STACK_ID) {
+            throw new IllegalArgumentException("Removing home stack is not allowed.");
+        }
+
         synchronized (this) {
-            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
-                    "removeTask()");
-            long ident = Binder.clearCallingIdentity();
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                final ActivityStack stack = mStackSupervisor.getStack(stackId);
+                if (stack == null) {
+                    return;
+                }
+                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
+                for (int i = tasks.size() - 1; i >= 0; i--) {
+                    removeTaskByIdLocked(
+                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @Override
+    public boolean removeTask(int taskId) {
+        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
+        synchronized (this) {
+            final long ident = Binder.clearCallingIdentity();
             try {
                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
             } finally {
@@ -10722,6 +10775,12 @@
             return;
         }
 
+        // We're only interested in providers that are encryption unaware, and
+        // we don't care about uninstalled apps, since there's no way they're
+        // running at this point.
+        final int matchFlags = GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE
+                | MATCH_DEBUG_TRIAGED_MISSING;
+
         synchronized (this) {
             final int NP = mProcessNames.getMap().size();
             for (int ip = 0; ip < NP; ip++) {
@@ -10736,8 +10795,7 @@
                         try {
                             final String pkgName = app.pkgList.keyAt(ig);
                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
-                                    .getPackageInfo(pkgName,
-                                            GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE, userId);
+                                    .getPackageInfo(pkgName, matchFlags, userId);
                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
                                 for (ProviderInfo provInfo : pkgInfo.providers) {
                                     Log.v(TAG, "Installing " + provInfo);
@@ -11052,6 +11110,16 @@
         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
     }
 
+    /** Notifies all listeners when the pinned stack animation ends. */
+    @Override
+    public void notifyPinnedStackAnimationEnded() {
+        synchronized (this) {
+            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
+            mHandler.obtainMessage(
+                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
+        }
+    }
+
     @Override
     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
@@ -14894,7 +14962,7 @@
                 pw.println(mi.hasActivities ? ",a" : ",e");
             } else {
                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
-                pw.println(mi.pss); pw.print(dumpSwapPss ? mi.swapPss : "N/A");
+                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
             }
             if (mi.subitems != null) {
                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
@@ -14959,6 +15027,9 @@
 
     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
             long realtime, boolean isCheckinRequest, boolean isCompact) {
+        if (isCompact) {
+            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
+        }
         if (isCheckinRequest || isCompact) {
             // short checkin version
             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
@@ -15017,6 +15088,9 @@
         return stringifySize(size * 1024, 1024);
     }
 
+    // Update this version number in case you change the 'compact' format
+    private static final int MEMINFO_COMPACT_VERSION = 1;
+
     final void dumpApplicationMemoryUsage(FileDescriptor fd,
             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
         boolean dumpDetails = false;
@@ -16729,10 +16803,12 @@
             HashSet<ComponentName> singleUserReceivers = null;
             boolean scannedFirstReceivers = false;
             for (int user : users) {
-                // Skip users that have Shell restrictions
+                // Skip users that have Shell restrictions, with exception of always permitted
+                // Shell broadcasts
                 if (callingUid == Process.SHELL_UID
                         && mUserController.hasUserRestriction(
-                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
+                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
+                        && !isPermittedShellBroadcast(intent)) {
                     continue;
                 }
                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
@@ -16799,6 +16875,11 @@
         return receivers;
     }
 
+    private boolean isPermittedShellBroadcast(Intent intent) {
+        // remote bugreport should always be allowed to be taken
+        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
+    }
+
     final int broadcastIntentLocked(ProcessRecord callerApp,
             String callerPackage, Intent intent, String resolvedType,
             IIntentReceiver resultTo, int resultCode, String resultData,
@@ -16890,6 +16971,8 @@
             if (isProtectedBroadcast
                     || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
                     || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
+                    || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
+                    || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
                     || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
                     || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
@@ -20340,8 +20423,8 @@
     }
 
     @Override
-    public boolean unlockUser(int userId, byte[] token) {
-        return mUserController.unlockUser(userId, token);
+    public boolean unlockUser(int userId, byte[] token, byte[] secret) {
+        return mUserController.unlockUser(userId, token, secret);
     }
 
     @Override
@@ -20758,7 +20841,7 @@
             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
         } catch (RemoteException e) {
         }
-        if (pkgUid == -1) {
+        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
             throw new IllegalArgumentException(
                     "Cannot kill dependents of non-existing package " + packageName);
         }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c352fc8..574b9db 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -25,6 +25,7 @@
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
 import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 
 import static android.content.res.Configuration.SCREENLAYOUT_UNDEFINED;
@@ -766,9 +767,8 @@
 
     void minimalResumeActivityLocked(ActivityRecord r) {
         r.state = ActivityState.RESUMED;
-        if (DEBUG_STATES) Slog.v(TAG_STATES,
-                "Moving to RESUMED: " + r + " (starting new instance)");
-        r.stopped = false;
+        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
+                + " callers=" + Debug.getCallers(5));
         mResumedActivity = r;
         r.task.touchActiveTime();
         mRecentTasks.addLocked(r.task);
@@ -1055,6 +1055,7 @@
                 if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                         + (timeout ? " (due to timeout)" : " (pause complete)"));
                 completePauseLocked(true);
+                return;
             } else {
                 EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                         r.userId, System.identityHashCode(r), r.shortComponentName,
@@ -1070,6 +1071,7 @@
                 }
             }
         }
+        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
     }
 
     final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
@@ -1097,6 +1099,9 @@
             mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
             r.stopped = true;
             r.state = ActivityState.STOPPED;
+
+            mWindowManager.notifyAppStopped(r.appToken);
+
             if (getVisibleBehindActivity() == r) {
                 mStackSupervisor.requestVisibleBehindLocked(r, false);
             }
@@ -1124,7 +1129,8 @@
                 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
                 prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
             } else if (prev.app != null) {
-                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending stop: " + prev);
+                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+                        + " wasStopping=" + wasStopping + " visible=" + prev.visible);
                 if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
                     if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                             "Complete pause, no longer waiting: " + prev);
@@ -1139,7 +1145,8 @@
                     // We can't clobber it, because the stop confirmation will not be handled.
                     // We don't need to schedule another stop, we only need to let it happen.
                     prev.state = ActivityState.STOPPING;
-                } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
+                } else if ((!prev.visible && !hasVisibleBehindActivity())
+                        || mService.isSleepingOrShuttingDown()) {
                     // If we were visible then resumeTopActivities will release resources before
                     // stopping.
                     addToStopping(prev);
@@ -1194,12 +1201,13 @@
             prev.cpuTimeAtResume = 0; // reset it
         }
 
-        // Notify when the task stack has changed, but only if visibilities changed (not just
-        // focus).
+        // Notify when the task stack has changed, but only if visibilities changed (not just focus)
         if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause) {
             mService.notifyTaskStackChangedLocked();
             mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
         }
+
+        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
     }
 
     private void addToStopping(ActivityRecord r) {
@@ -1223,9 +1231,11 @@
      * this function updates the rest of our state to match that fact.
      */
     private void completeResumeLocked(ActivityRecord next) {
+        next.visible = true;
         next.idle = false;
         next.results = null;
         next.newIntents = null;
+        next.stopped = false;
 
         if (next.isHomeActivity()) {
             ProcessRecord app = next.task.mActivities.get(0).app;
@@ -1561,7 +1571,7 @@
                             resumeNextActivity = false;
                         }
                     } else {
-                        makeVisible(starting, r);
+                        makeVisibleIfNeeded(starting, r);
                     }
                     // Aggregate current change flags.
                     configChanges |= r.configChangeFlags;
@@ -1584,6 +1594,33 @@
                 // determined individually unlike other stacks where the visibility or fullscreen
                 // status of an activity in a previous task affects other.
                 behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
+            } else if (mStackId == HOME_STACK_ID) {
+                if (task.isHomeTask()) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
+                            + " stackInvisible=" + stackInvisible
+                            + " behindFullscreenActivity=" + behindFullscreenActivity);
+                    // No other task in the home stack should be visible behind the home activity.
+                    // Home activities is usually a translucent activity with the wallpaper behind
+                    // them. However, when they don't have the wallpaper behind them, we want to
+                    // show activities in the next application stack behind them vs. another
+                    // task in the home stack like recents.
+                    behindFullscreenActivity = true;
+                } else if (task.isRecentsTask()
+                        && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
+                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
+                            "Recents task returning to app: at " + task
+                                    + " stackInvisible=" + stackInvisible
+                                    + " behindFullscreenActivity=" + behindFullscreenActivity);
+                    // We don't want any other tasks in the home stack visible if the recents
+                    // activity is going to be returning to an application activity type.
+                    // We do this to preserve the visible order the user used to get into the
+                    // recents activity. The recents activity is normally translucent and if it
+                    // doesn't have the wallpaper behind it the next activity in the home stack
+                    // shouldn't be visible when the home stack is brought to the front to display
+                    // the recents activity from an app.
+                    behindFullscreenActivity = true;
+                }
+
             }
         }
 
@@ -1684,33 +1721,7 @@
                         + " behindFullscreenActivity=" + behindFullscreenActivity);
             // At this point, nothing else needs to be shown in this task.
             behindFullscreenActivity = true;
-        } else if (isHomeStack()) {
-            if (r.isHomeActivity()) {
-                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home activity: at " + r
-                        + " stackInvisible=" + stackInvisible
-                        + " behindFullscreenActivity=" + behindFullscreenActivity);
-                // No other activity in the home stack should be visible behind the home activity.
-                // Home activities is usually a translucent activity with the wallpaper behind them.
-                // However, when they don't have the wallpaper behind them, we want to show
-                // activities in the next application stack behind them vs. another activity in the
-                // home stack like recents.
-                behindFullscreenActivity = true;
-            } else if (r.isRecentsActivity()
-                    && task.getTaskToReturnTo() == APPLICATION_ACTIVITY_TYPE) {
-                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
-                        "Recents activity returning to app: at " + r
-                        + " stackInvisible=" + stackInvisible
-                        + " behindFullscreenActivity=" + behindFullscreenActivity);
-                // We don't want any other activities in the home stack visible if the recents
-                // activity is going to be returning to an application activity type.
-                // We do this to preserve the visible order the user used to get into the recents
-                // activity. The recents activity is normally translucent and if it doesn't have
-                // the wallpaper behind it the next activity in the home stack shouldn't be visible
-                // when the home stack is brought to the front to display the recents activity from
-                // an app.
-                behindFullscreenActivity = true;
-            }
-        } else if (r.frontOfTask && task.isOverHomeStack()) {
+        } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
             if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
                     + " stackInvisible=" + stackInvisible
                     + " behindFullscreenActivity=" + behindFullscreenActivity);
@@ -1719,28 +1730,32 @@
         return behindFullscreenActivity;
     }
 
-    private void makeVisible(ActivityRecord starting, ActivityRecord r) {
+    private void makeVisibleIfNeeded(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);
+        if (r.state == ActivityState.RESUMED || r == starting) {
+            if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
+                    "Not making visible, r=" + r + " state=" + r.state + " starting=" + starting);
+            return;
+        }
+
+        // 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);
         }
     }
 
@@ -1887,7 +1902,7 @@
             return false;
         }
 
-        cancelInitializingActivities();
+        mStackSupervisor.cancelInitializingActivities();
 
         // Find the first activity that is not finishing.
         final ActivityRecord next = topRunningActivityLocked();
@@ -1994,8 +2009,7 @@
 
         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
 
-        // If we are currently pausing an activity, then don't do anything
-        // until that is done.
+        // If we are currently pausing an activity, then don't do anything until that is done.
         if (!mStackSupervisor.allPausedActivitiesComplete()) {
             if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                     "resumeTopActivityLocked: Skip resume: some activity pausing.");
@@ -2003,40 +2017,10 @@
             return false;
         }
 
-        // Okay we are now going to start a switch, to 'next'.  We may first
-        // have to pause the current activity, but this is an important point
-        // where we have decided to go to 'next' so keep track of that.
-        // XXX "App Redirected" dialog is getting too many false positives
-        // at this point, so turn off for now.
-        if (false) {
-            if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
-                long now = SystemClock.uptimeMillis();
-                final boolean inTime = mLastStartedActivity.startTime != 0
-                        && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
-                final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
-                final int nextUid = next.info.applicationInfo.uid;
-                if (inTime && lastUid != nextUid
-                        && lastUid != next.launchedFromUid
-                        && mService.checkPermission(
-                                android.Manifest.permission.STOP_APP_SWITCHES,
-                                -1, next.launchedFromUid)
-                        != PackageManager.PERMISSION_GRANTED) {
-                    mService.showLaunchWarningLocked(mLastStartedActivity, next);
-                } else {
-                    next.startTime = now;
-                    mLastStartedActivity = next;
-                }
-            } else {
-                next.startTime = SystemClock.uptimeMillis();
-                mLastStartedActivity = next;
-            }
-        }
-
         mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
 
-        // We need to start pausing the current activity so the top one
-        // can be resumed...
-        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
+        // We need to start pausing the current activity so the top one can be resumed...
+        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
         boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
         if (mResumedActivity != null) {
             if (DEBUG_STATES) Slog.d(TAG_STATES,
@@ -2283,7 +2267,6 @@
             // From this point on, if something goes wrong there is no way
             // to recover the activity.
             try {
-                next.visible = true;
                 completeResumeLocked(next);
             } catch (Exception e) {
                 // If any exception gets thrown, toss away this
@@ -2294,8 +2277,6 @@
                 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                 return true;
             }
-            next.stopped = false;
-
         } else {
             // Whoops, need to restart this activity!
             if (!next.hasBeenLaunched) {
@@ -4275,6 +4256,12 @@
                 // "restart!".
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                         "Config is relaunching resumed " + r);
+
+                if (DEBUG_STATES && !r.visible) {
+                    Slog.v(TAG_STATES, "Config is relaunching resumed invisible activity " + r
+                            + " called by " + Debug.getCallers(4));
+                }
+
                 relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow);
             } else {
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -4411,7 +4398,8 @@
 
         try {
             if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
-                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r);
+                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r
+                    + " callers=" + Debug.getCallers(6));
             r.forceNewConfig = false;
             r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
                     !andResume, new Configuration(mService.mConfiguration),
@@ -4425,9 +4413,21 @@
         }
 
         if (andResume) {
-            r.results = null;
-            r.newIntents = null;
+            if (DEBUG_STATES) {
+                Slog.d(TAG_STATES, "Resumed after relaunch " + r);
+            }
             r.state = ActivityState.RESUMED;
+            // Relaunch-resume could happen either when the app is already in the front,
+            // or while it's being brought to front. In the latter case, it's marked RESUMED
+            // but not yet visible (or stopped). We need to complete the resume here as the
+            // code in resumeTopActivityInnerLocked to complete the resume might be skipped.
+            if (!r.visible || r.stopped) {
+                mWindowManager.setAppVisibility(r.appToken, true);
+                completeResumeLocked(r);
+            } else {
+                r.results = null;
+                r.newIntents = null;
+            }
         } else {
             mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
             r.state = ActivityState.PAUSED;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f53e71a..c143474 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -148,6 +148,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
@@ -907,6 +908,15 @@
         }
     }
 
+    void cancelInitializingActivities() {
+        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
+                stacks.get(stackNdx).cancelInitializingActivities();
+            }
+        }
+    }
+
     void reportActivityVisibleLocked(ActivityRecord r) {
         sendWaitingVisibleReportLocked(r);
     }
@@ -1045,10 +1055,14 @@
     }
 
     ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
+        return resolveIntent(intent, resolvedType, userId, 0);
+    }
+
+    ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
         try {
             return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
-                            PackageManager.MATCH_DEFAULT_ONLY
-                            | ActivityManagerService.STOCK_PM_FLAGS, userId);
+                    PackageManager.MATCH_DEFAULT_ONLY | flags
+                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
         } catch (RemoteException e) {
         }
         return null;
@@ -1060,9 +1074,18 @@
         return resolveActivity(intent, rInfo, startFlags, profilerInfo);
     }
 
-    final boolean realStartActivityLocked(ActivityRecord r,
-            ProcessRecord app, boolean andResume, boolean checkConfig)
-            throws RemoteException {
+    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
+            boolean andResume, boolean checkConfig) throws RemoteException {
+
+        if (!allPausedActivitiesComplete()) {
+            // While there are activities pausing we skipping starting any new activities until
+            // pauses are complete. NOTE: that we also do this for activities that are starting in
+            // the paused state because they will first be resumed then paused on the client side.
+            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
+                    "realStartActivityLocked: Skipping start of r=" + r
+                    + " some activities pausing...");
+            return false;
+        }
 
         if (andResume) {
             r.startFreezingScreenLocked(app, 0);
@@ -1932,14 +1955,11 @@
 
     private void ensureConfigurationAndResume(ActivityStack stack, ActivityRecord r,
             boolean preserveWindows) {
-        if (r == null) {
+        if (r == null || !r.visible) {
             return;
         }
         final boolean updated = stack.ensureActivityConfigurationLocked(r, 0,
                 preserveWindows);
-        // And we need to make sure at this point that all other activities
-        // are made visible with the correct configuration.
-        ensureActivitiesVisibleLocked(r, 0, preserveWindows);
         if (!updated) {
             resumeFocusedStackTopActivityLocked();
         }
@@ -2261,7 +2281,7 @@
         boolean kept = true;
         try {
             final ActivityStack stack = moveTaskToStackUncheckedLocked(
-                    task, stackId, toTop, forceFocus, "moveTaskToStack:" + reason);
+                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
             stackId = stack.mStackId;
 
             if (!animate) {
@@ -2321,36 +2341,44 @@
             return false;
         }
 
-        moveActivityToStackLocked(r, PINNED_STACK_ID, "moveTopActivityToPinnedStack", null);
-        mWindowManager.animateResizePinnedStack(bounds);
+        moveActivityToPinnedStackLocked(r, "moveTopActivityToPinnedStack", bounds);
         return true;
     }
 
-    void moveActivityToStackLocked(ActivityRecord r, int stackId, String reason, Rect bounds) {
-        final TaskRecord task = r.task;
-        if (task.mActivities.size() == 1) {
-            // There is only one activity in the task. So, we can just move the task over to the
-            // stack without re-parenting the activity in a different task.
-            moveTaskToStackLocked(
-                    task.taskId, stackId, ON_TOP, FORCE_FOCUS, reason, true /* animate */);
-        } else {
-            final ActivityStack stack = getStack(stackId, CREATE_IF_NEEDED, ON_TOP);
-            stack.moveActivityToStack(r);
+    void moveActivityToPinnedStackLocked(ActivityRecord r, String reason, Rect bounds) {
+        mWindowManager.deferSurfaceLayout();
+        try {
+            final TaskRecord task = r.task;
+
+            // Need to make sure the pinned stack exist so we can resize it below...
+            final ActivityStack stack = getStack(PINNED_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
+
+            // Resize the pinned stack to match the current size of the task the activity we are
+            // going to be moving is currently contained in. We do this to have the right starting
+            // animation bounds for the pinned stack to the desired bounds the caller wants.
+            resizeStackLocked(PINNED_STACK_ID, task.mBounds, null /* tempTaskBounds */,
+                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS,
+                    true /* allowResizeInDockedMode */);
+
+            if (task.mActivities.size() == 1) {
+                // There is only one activity in the task. So, we can just move the task over to
+                // the stack without re-parenting the activity in a different task.
+                moveTaskToStackLocked(
+                        task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE);
+            } else {
+                stack.moveActivityToStack(r);
+            }
+        } finally {
+            mWindowManager.continueSurfaceLayout();
         }
 
-        if (bounds != null) {
-            resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
-                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, true);
-        }
-
-        // The task might have already been running and its visibility needs to be synchronized with
-        // the visibility of the stack / windows.
+        // The task might have already been running and its visibility needs to be synchronized
+        // with the visibility of the stack / windows.
         ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
         resumeFocusedStackTopActivityLocked();
 
-        if (stackId == PINNED_STACK_ID) {
-            mService.notifyActivityPinnedLocked();
-        }
+        mWindowManager.animateResizePinnedStack(bounds);
+        mService.notifyActivityPinnedLocked();
     }
 
     void positionTaskInStackLocked(int taskId, int stackId, int position) {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 1ed749f..9b2bca0 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.server.am;
 
 import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index b360b89..1166ae1 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.server.am;
 
 import static android.app.Activity.RESULT_CANCELED;
@@ -74,7 +90,9 @@
 import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Binder;
@@ -84,6 +102,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.EventLog;
 import android.util.Slog;
@@ -582,6 +601,22 @@
         intent = new Intent(intent);
 
         ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
+        if (rInfo == null) {
+            UserInfo userInfo = mSupervisor.getUserInfo(userId);
+            if (userInfo != null && userInfo.isManagedProfile()) {
+                // Special case for managed profiles, if attempting to launch non-cryto aware
+                // app in a locked managed profile from an unlocked parent allow it to resolve
+                // as user will be sent via confirm credentials to unlock the profile.
+                UserManager userManager = UserManager.get(mService.mContext);
+                UserInfo parent = userManager.getProfileParent(userId);
+                if (parent != null
+                        && userManager.isUserUnlocked(parent.getUserHandle())
+                        && !userManager.isUserUnlocked(userInfo.getUserHandle())) {
+                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
+                            PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE);
+                }
+            }
+        }
         // Collect information about the target of the Intent.
         ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
 
@@ -1001,7 +1036,7 @@
                 // If the activity is not focusable, we can't resume it, but still would like to
                 // make sure it becomes visible as it starts (this will also trigger entry
                 // animation). An example of this are PIP activities.
-                mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
+                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
             }
         } else {
             mTargetStack.addRecentActivityLocked(mStartActivity);
@@ -1362,7 +1397,7 @@
                 }
                 intentActivity.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
                         mStartActivity.launchedFromPackage);
-            } else if (!mStartActivity.intent.filterEquals(intentActivity.task.intent)) {
+            } else if (!mStartActivity.intent.filterEquals(intentActivity.intent)) {
                 // In this case we are launching the root activity of the task, but with a
                 // different intent. We should start a new instance on top.
                 mAddingToTask = true;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 10f0977..16fd909 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -70,6 +70,7 @@
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
@@ -122,9 +123,6 @@
     private static final String ATTR_TASK_AFFILIATION_COLOR = "task_affiliation_color";
     private static final String ATTR_CALLING_UID = "calling_uid";
     private static final String ATTR_CALLING_PACKAGE = "calling_package";
-    // TODO(b/26847884): Currently needed while migrating to resize_mode.
-    // Can be removed at some later point.
-    private static final String ATTR_RESIZEABLE = "resizeable";
     private static final String ATTR_RESIZE_MODE = "resize_mode";
     private static final String ATTR_PRIVILEGED = "privileged";
     private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds";
@@ -933,10 +931,15 @@
         }
         return false;
     }
+
     boolean isHomeTask() {
         return taskType == HOME_ACTIVITY_TYPE;
     }
 
+    boolean isRecentsTask() {
+        return taskType == RECENTS_ACTIVITY_TYPE;
+    }
+
     boolean isApplicationTask() {
         return taskType == APPLICATION_ACTIVITY_TYPE;
     }
@@ -1006,6 +1009,7 @@
             String label = null;
             String iconFilename = null;
             int colorPrimary = 0;
+            int colorBackground = 0;
             for (--activityNdx; activityNdx >= 0; --activityNdx) {
                 final ActivityRecord r = mActivities.get(activityNdx);
                 if (r.taskDescription != null) {
@@ -1018,9 +1022,13 @@
                     if (colorPrimary == 0) {
                         colorPrimary = r.taskDescription.getPrimaryColor();
                     }
+                    if (colorBackground == 0) {
+                        colorBackground = r.taskDescription.getBackgroundColor();
+                    }
                 }
             }
-            lastTaskDescription = new TaskDescription(label, colorPrimary, iconFilename);
+            lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary,
+                    colorBackground);
             // Update the task affiliation color if we are the parent of the group
             if (taskId == mAffiliatedTaskId) {
                 mAffiliatedTaskColor = lastTaskDescription.getPrimaryColor();
@@ -1164,7 +1172,7 @@
         int nextTaskId = INVALID_TASK_ID;
         int callingUid = -1;
         String callingPackage = "";
-        int resizeMode = RESIZE_MODE_UNRESIZEABLE;
+        int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
         boolean privileged = false;
         Rect bounds = null;
 
@@ -1226,11 +1234,10 @@
                 callingUid = Integer.valueOf(attrValue);
             } else if (ATTR_CALLING_PACKAGE.equals(attrName)) {
                 callingPackage = attrValue;
-            } else if (ATTR_RESIZEABLE.equals(attrName)) {
-                resizeMode = Boolean.valueOf(attrValue)
-                        ? RESIZE_MODE_RESIZEABLE : RESIZE_MODE_CROP_WINDOWS;
             } else if (ATTR_RESIZE_MODE.equals(attrName)) {
                 resizeMode = Integer.valueOf(attrValue);
+                resizeMode = (resizeMode == RESIZE_MODE_CROP_WINDOWS)
+                        ? RESIZE_MODE_FORCE_RESIZEABLE : resizeMode;
             } else if (ATTR_PRIVILEGED.equals(attrName)) {
                 privileged = Boolean.valueOf(attrValue);
             } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) {
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 2f63b2d3..4e6dc3a 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -165,15 +165,15 @@
         void register(ContentResolver resolver) {
             resolver.registerContentObserver(mUserSetupComplete, false, this, UserHandle.USER_ALL);
             synchronized (mService) {
-                updateCurrentUserSetupCompleteLocked();
+                updateUserSetupCompleteLocked(UserHandle.USER_ALL);
             }
         }
 
         @Override
-        public void onChange(boolean selfChange, Uri uri) {
+        public void onChange(boolean selfChange, Uri uri, int userId) {
             if (mUserSetupComplete.equals(uri)) {
                 synchronized (mService) {
-                    updateCurrentUserSetupCompleteLocked();
+                    updateUserSetupCompleteLocked(userId);
                 }
             }
         }
@@ -297,6 +297,22 @@
                         null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                         userId);
 
+                if (getUserInfo(userId).isManagedProfile()) {
+                    UserInfo parent = getUserManager().getProfileParent(userId);
+                    if (parent != null) {
+                        final Intent profileUnlockedIntent = new Intent(
+                                Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
+                        profileUnlockedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
+                        profileUnlockedIntent.addFlags(
+                                Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                                | Intent.FLAG_RECEIVER_FOREGROUND);
+                        mService.broadcastIntentLocked(null, null, profileUnlockedIntent,
+                                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
+                                null, false, false, MY_PID, SYSTEM_UID,
+                                parent.id);
+                    }
+                }
+
                 final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                 bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                 bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
@@ -655,7 +671,7 @@
                 final Integer userIdInt = userId;
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
-                updateCurrentUserSetupCompleteLocked();
+                updateUserSetupCompleteLocked(userId);
 
                 if (foreground) {
                     mCurrentUserId = userId;
@@ -783,7 +799,7 @@
         return result;
     }
 
-    boolean unlockUser(final int userId, byte[] token) {
+    boolean unlockUser(final int userId, byte[] token, byte[] secret) {
         if (mService.checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: unlockUser() from pid="
@@ -796,7 +812,7 @@
 
         final long binderToken = Binder.clearCallingIdentity();
         try {
-            return unlockUserCleared(userId, token);
+            return unlockUserCleared(userId, token, secret);
         } finally {
             Binder.restoreCallingIdentity(binderToken);
         }
@@ -810,10 +826,10 @@
      */
     boolean maybeUnlockUser(final int userId) {
         // Try unlocking storage using empty token
-        return unlockUserCleared(userId, null);
+        return unlockUserCleared(userId, null, null);
     }
 
-    boolean unlockUserCleared(final int userId, byte[] token) {
+    boolean unlockUserCleared(final int userId, byte[] token, byte[] secret) {
         synchronized (mService) {
             // Bail if already running unlocked
             final UserState uss = mStartedUsers.get(userId);
@@ -824,7 +840,7 @@
             final UserInfo userInfo = getUserInfo(userId);
             final IMountService mountService = getMountService();
             try {
-                mountService.unlockUserKey(userId, userInfo.serialNumber, token);
+                mountService.unlockUserKey(userId, userInfo.serialNumber, token, secret);
             } catch (RemoteException | RuntimeException e) {
                 Slog.w(TAG, "Failed to unlock: " + e.getMessage());
                 return false;
@@ -870,11 +886,16 @@
         mUserSwitchObservers.finishBroadcast();
     }
 
-    void updateCurrentUserSetupCompleteLocked() {
+    void updateUserSetupCompleteLocked(int userId) {
         final ContentResolver cr = mService.mContext.getContentResolver();
-        final boolean setupComplete =
-                Settings.Secure.getIntForUser(cr, USER_SETUP_COMPLETE, 0, mCurrentUserId) != 0;
-        mSetupCompletedUsers.put(mCurrentUserId, setupComplete);
+        for (int i = mStartedUsers.size() - 1; i >= 0; i--) {
+            int startedUser = mStartedUsers.keyAt(i);
+            if (startedUser == userId || userId == UserHandle.USER_ALL) {
+                final boolean setupComplete =
+                        Settings.Secure.getIntForUser(cr, USER_SETUP_COMPLETE, 0, startedUser) != 0;
+                mSetupCompletedUsers.put(startedUser, setupComplete);
+            }
+        }
     }
 
     boolean isUserSetupCompleteLocked(int userId) {
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 5806f3f..a6325a4 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -20,6 +20,7 @@
 import android.media.AudioRecordConfiguration;
 import android.media.AudioSystem;
 import android.media.IRecordingConfigDispatcher;
+import android.media.MediaRecorder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
@@ -48,6 +49,9 @@
      * Implementation of android.media.AudioSystem.AudioRecordingCallback
      */
     public void onRecordingConfigurationChanged(int event, int session, int source) {
+        if (MediaRecorder.isSystemOnlyAudioSource(source)) {
+            return;
+        }
         if (updateSnapshot(event, session, source)) {
             final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
             synchronized(mClients) {
diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
index 5fd39c0..dc62609 100644
--- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
+++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java
@@ -49,7 +49,9 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Random;
 
@@ -107,27 +109,33 @@
     // so callers can wait for completion.
     private final CountDownLatch mCountDownLatch;
 
-    private class Measurement {
+    public class Measurement {
         private static final String SUCCEEDED = "SUCCEEDED";
         private static final String FAILED = "FAILED";
 
-        // TODO: Refactor to make these private for better encapsulation.
-        public String description = "";
-        public long startTime;
-        public long finishTime;
-        public String result = "";
-        public Thread thread;
+        private boolean succeeded;
 
-        public void recordSuccess(String msg) {
+        // Package private.  TODO: investigate better encapsulation.
+        String description = "";
+        long startTime;
+        long finishTime;
+        String result = "";
+        Thread thread;
+
+        public boolean checkSucceeded() { return succeeded; }
+
+        void recordSuccess(String msg) {
             maybeFixupTimes();
+            succeeded = true;
             result = SUCCEEDED + ": " + msg;
             if (mCountDownLatch != null) {
                 mCountDownLatch.countDown();
             }
         }
 
-        public void recordFailure(String msg) {
+        void recordFailure(String msg) {
             maybeFixupTimes();
+            succeeded = false;
             result = FAILED + ": " + msg;
             if (mCountDownLatch != null) {
                 mCountDownLatch.countDown();
@@ -265,6 +273,51 @@
         } catch (InterruptedException ignored) {}
     }
 
+    public List<Measurement> getMeasurements() {
+        // TODO: Consider moving waitForMeasurements() in here to minimize the
+        // chance of caller errors.
+
+        ArrayList<Measurement> measurements = new ArrayList(totalMeasurementCount());
+
+        // Sort measurements IPv4 first.
+        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet4Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+        for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
+                mExplicitSourceIcmpChecks.entrySet()) {
+            if (entry.getKey().first instanceof Inet4Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet4Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+
+        // IPv6 measurements second.
+        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet6Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+        for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
+                mExplicitSourceIcmpChecks.entrySet()) {
+            if (entry.getKey().first instanceof Inet6Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
+            if (entry.getKey() instanceof Inet6Address) {
+                measurements.add(entry.getValue());
+            }
+        }
+
+        return measurements;
+    }
+
     public void dump(IndentingPrintWriter pw) {
         pw.println(TAG + ":" + mDescription);
         final long unfinished = mCountDownLatch.getCount();
@@ -276,30 +329,13 @@
         }
 
         pw.increaseIndent();
-        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
-            if (entry.getKey() instanceof Inet4Address) {
-                pw.println(entry.getValue().toString());
-            }
+
+        String prefix;
+        for (Measurement m : getMeasurements()) {
+            prefix = m.checkSucceeded() ? "." : "F";
+            pw.println(prefix + "  " + m.toString());
         }
-        for (Map.Entry<InetAddress, Measurement> entry : mIcmpChecks.entrySet()) {
-            if (entry.getKey() instanceof Inet6Address) {
-                pw.println(entry.getValue().toString());
-            }
-        }
-        for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry :
-                mExplicitSourceIcmpChecks.entrySet()) {
-            pw.println(entry.getValue().toString());
-        }
-        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
-            if (entry.getKey() instanceof Inet4Address) {
-                pw.println(entry.getValue().toString());
-            }
-        }
-        for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) {
-            if (entry.getKey() instanceof Inet6Address) {
-                pw.println(entry.getValue().toString());
-            }
-        }
+
         pw.decreaseIndent();
     }
 
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index fd9abff..f231f92 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -190,6 +190,7 @@
             if (!setPackageAuthorization(packageName, true)) {
                 return false;
             }
+            prepareInternal(packageName);
         }
 
         // Save the new package name in Settings.Secure.
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index daf839a..0d97434 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -62,6 +62,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -70,40 +71,42 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
-import android.os.Messenger;
 import android.provider.Settings;
 import android.text.format.DateUtils;
 import android.text.format.Time;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.Slog;
 import android.util.Pair;
-
+import android.util.Slog;
 import android.util.SparseArray;
+
+import com.google.android.collect.Lists;
+import com.google.android.collect.Maps;
+
 import com.android.internal.R;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.accounts.AccountManagerService;
+import com.android.server.backup.AccountSyncSettingsBackupHelper;
 import com.android.server.content.SyncStorageEngine.AuthorityInfo;
 import com.android.server.content.SyncStorageEngine.EndPoint;
 import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Random;
-import java.util.List;
-import java.util.HashSet;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Map;
-import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Random;
+import java.util.Set;
 
 /**
  * Implementation details:
@@ -178,18 +181,6 @@
     private static final int SYNC_MONITOR_PROGRESS_THRESHOLD_BYTES = 10; // 10 bytes
 
     /**
-     * How long to delay each queued {@link SyncHandler} message that may have occurred before boot
-     * or befor the device became provisioned.
-     */
-    private static final long PER_SYNC_BOOT_DELAY_MILLIS = 1000L;  // 1 second
-
-    /**
-     * The maximum amount of time we're willing to delay syncs out of boot, after device has been
-     * provisioned, etc.
-     */
-    private static final long MAX_SYNC_BOOT_DELAY_MILLIS = 60000L;  // 1 minute
-
-    /**
      * If a previously scheduled sync becomes ready and we are low on storage, it gets
      * pushed back for this amount of time.
      */
@@ -242,12 +233,24 @@
     private SparseArray<SyncOperation> mScheduledSyncs = new SparseArray<SyncOperation>(32);
     private final Random mRand;
 
-    private int getUnusedJobId() {
-        synchronized (mScheduledSyncs) {
-            int newJobId = mRand.nextInt(Integer.MAX_VALUE);
-            while (mScheduledSyncs.indexOfKey(newJobId) >= 0) {
-                newJobId = mRand.nextInt(Integer.MAX_VALUE);
+    private boolean isJobIdInUseLockedH(int jobId) {
+        if (mScheduledSyncs.indexOfKey(jobId) >= 0) {
+            return true;
+        }
+        for (ActiveSyncContext asc: mActiveSyncContexts) {
+            if (asc.mSyncOperation.jobId == jobId) {
+                return true;
             }
+        }
+        return false;
+    }
+
+    private int getUnusedJobIdH() {
+        synchronized (mScheduledSyncs) {
+            int newJobId;
+            do {
+                newJobId = mRand.nextInt(Integer.MAX_VALUE);
+            } while (isJobIdInUseLockedH(newJobId));
             return newJobId;
         }
     }
@@ -425,6 +428,73 @@
         }
     }
 
+    /**
+     * Cancel all unnecessary jobs. This function will be run once after every boot.
+     */
+    private void cleanupJobs() {
+        // O(n^2) in number of jobs, so we run this on the background thread.
+        mSyncHandler.postAtFrontOfQueue(new Runnable() {
+            @Override
+            public void run() {
+                List<SyncOperation> ops = getAllPendingSyncsFromCache();
+                Set<String> cleanedKeys = new HashSet<String>();
+                for (SyncOperation opx: ops) {
+                    if (cleanedKeys.contains(opx.key)) {
+                        continue;
+                    }
+                    cleanedKeys.add(opx.key);
+                    for (SyncOperation opy: ops) {
+                        if (opx == opy) {
+                            continue;
+                        }
+                        if (opx.key.equals(opy.key)) {
+                            removeSyncOperationFromCache(opy.jobId);
+                            mJobScheduler.cancel(opy.jobId);
+                        }
+                    }
+                }
+                ensureDefaultPeriodicSyncsH();
+            }
+        });
+    }
+
+    private void ensureDefaultPeriodicSyncsH() {
+
+        long defaultPeriod = SyncStorageEngine.DEFAULT_POLL_FREQUENCY_SECONDS;
+        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(defaultPeriod);
+
+        List<AuthorityInfo> authorities = mSyncStorageEngine.getAllAuthorities();
+        List<SyncOperation> syncs = getAllPendingSyncsFromCache();
+        for (AuthorityInfo authority: authorities) {
+            boolean foundPeriodicSync = false;
+            for (SyncOperation op: syncs) {
+                if (op.isPeriodic && authority.target.matchesSpec(op.target)) {
+                    foundPeriodicSync = true;
+                    break;
+                }
+            }
+            if (!foundPeriodicSync) {
+                EndPoint target = authority.target;
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType>
+                        syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(
+                                target.provider, target.account.type),
+                        target.userId);
+                if (syncAdapterInfo == null) {
+                    continue;
+                }
+                scheduleSyncOperationH(
+                    new SyncOperation(target, syncAdapterInfo.uid,
+                            syncAdapterInfo.componentName.getPackageName(),
+                            SyncOperation.REASON_PERIODIC, SyncStorageEngine.SOURCE_PERIODIC,
+                            new Bundle(), syncAdapterInfo.type.allowParallelSyncs(),
+                            true /* periodic */, SyncOperation.NO_JOB_ID, defaultPeriod * 1000L,
+                            defaultFlex * 1000L)
+                );
+            }
+        }
+    }
+
     private synchronized void verifyJobScheduler() {
         if (mJobScheduler != null) {
             return;
@@ -449,6 +519,7 @@
                 }
             }
         }
+        cleanupJobs();
     }
 
     private JobScheduler getJobScheduler() {
@@ -479,12 +550,12 @@
 
         mSyncStorageEngine.setPeriodicSyncAddedListener(
                 new SyncStorageEngine.PeriodicSyncAddedListener() {
-            @Override
-            public void onPeriodicSyncAdded(EndPoint target, Bundle extras, long pollFrequency,
-                                            long flex) {
-                updateOrAddPeriodicSync(target, pollFrequency, flex, extras);
-            }
-        });
+                    @Override
+                    public void onPeriodicSyncAdded(EndPoint target, Bundle extras, long pollFrequency,
+                            long flex) {
+                        updateOrAddPeriodicSync(target, pollFrequency, flex, extras);
+                    }
+                });
 
         mSyncStorageEngine.setOnAuthorityRemovedListener(new SyncStorageEngine.OnAuthorityRemovedListener() {
             @Override
@@ -719,10 +790,9 @@
      * @param onlyThoseWithUnkownSyncableState Only sync authorities that have unknown state.
      */
     public void scheduleSync(Account requestedAccount, int userId, int reason,
-                             String requestedAuthority, Bundle extras, long beforeRuntimeMillis,
-                             long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
+            String requestedAuthority, Bundle extras, long beforeRuntimeMillis,
+            long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
         final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
-        EndPoint ep = new EndPoint(requestedAccount,requestedAuthority, userId);
         if (extras == null) {
             extras = new Bundle();
         }
@@ -911,7 +981,7 @@
      * flexMillis will be updated.
      */
     public void updateOrAddPeriodicSync(EndPoint target, long pollFrequency, long flex,
-                                        Bundle extras) {
+            Bundle extras) {
         UpdatePeriodicSyncMessagePayload payload = new UpdatePeriodicSyncMessagePayload(target,
                 pollFrequency, flex, extras);
         mSyncHandler.obtainMessage(SyncHandler.MESSAGE_UPDATE_PERIODIC_SYNC, payload)
@@ -965,7 +1035,7 @@
     }
 
     private void sendSyncFinishedOrCanceledMessage(ActiveSyncContext syncContext,
-                                                   SyncResult syncResult) {
+            SyncResult syncResult) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Slog.v(TAG, "sending MESSAGE_SYNC_FINISHED");
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_SYNC_FINISHED;
@@ -1023,7 +1093,7 @@
         public final SyncResult syncResult;
 
         SyncFinishedOrCancelledMessagePayload(ActiveSyncContext syncContext,
-                                              SyncResult syncResult) {
+                SyncResult syncResult) {
             this.activeSyncContext = syncContext;
             this.syncResult = syncResult;
         }
@@ -1036,7 +1106,7 @@
         public final Bundle extras;
 
         UpdatePeriodicSyncMessagePayload(EndPoint target, long pollFrequency, long flex,
-                                         Bundle extras) {
+                Bundle extras) {
             this.target = target;
             this.pollFrequency = pollFrequency;
             this.flex = flex;
@@ -1197,7 +1267,18 @@
         }
 
         // Check if duplicate syncs are pending. If found, keep one with least expected run time.
-        if (!syncOperation.isReasonPeriodic()) {
+        if (!syncOperation.isPeriodic) {
+            // Check currently running syncs
+            for (ActiveSyncContext asc: mActiveSyncContexts) {
+                if (asc.mSyncOperation.key.equals(syncOperation.key)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "Duplicate sync is already running. Not scheduling "
+                                + syncOperation);
+                    }
+                    return;
+                }
+            }
+
             int duplicatesCount = 0;
             long now = SystemClock.elapsedRealtime();
             syncOperation.expectedRuntime = now + minDelay;
@@ -1240,21 +1321,23 @@
             }
         }
 
-        syncOperation.jobId = getUnusedJobId();
+        // Syncs that are re-scheduled shouldn't get a new job id.
+        if (syncOperation.jobId == SyncOperation.NO_JOB_ID) {
+            syncOperation.jobId = getUnusedJobIdH();
+        }
         addSyncOperationToCache(syncOperation);
 
         if (isLoggable) {
-            Slog.v(TAG, "scheduling sync operation " + syncOperation.target.toString());
+            Slog.v(TAG, "scheduling sync operation " + syncOperation.toString());
         }
 
-        // This is done to give preference to syncs that are not pushed back.
         int priority = syncOperation.findPriority();
 
         final int networkType = syncOperation.isNotAllowedOnMetered() ?
                 JobInfo.NETWORK_TYPE_UNMETERED : JobInfo.NETWORK_TYPE_ANY;
 
         JobInfo.Builder b = new JobInfo.Builder(syncOperation.jobId,
-                    new ComponentName(mContext, SyncJobService.class))
+                new ComponentName(mContext, SyncJobService.class))
                 .setExtras(syncOperation.toJobInfoExtras())
                 .setRequiredNetworkType(networkType)
                 .setPersisted(true)
@@ -1343,7 +1426,7 @@
                 Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
                         + "encountered an error: " + operation);
             }
-            scheduleSyncOperationH(operation, 0 /* immediately */);
+            scheduleSyncOperationH(operation);
         } else if (syncResult.tooManyRetries) {
             // If this sync aborted because the internal sync loop retried too many times then
             //   don't reschedule. Otherwise we risk getting into a retry loop.
@@ -1357,7 +1440,7 @@
                 Log.d(TAG, "retrying sync operation because even though it had an error "
                         + "it achieved some success");
             }
-            scheduleSyncOperationH(operation, 0 /* immediately */);
+            scheduleSyncOperationH(operation);
         } else if (syncResult.syncAlreadyInProgress) {
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation that failed because there was already a "
@@ -1459,7 +1542,7 @@
          * for this sync. This is used to attribute the wakelock hold to that application.
          */
         public ActiveSyncContext(SyncOperation syncOperation, long historyRowId,
-                                 int syncAdapterUid) {
+                int syncAdapterUid) {
             super();
             mSyncAdapterUid = syncAdapterUid;
             mSyncOperation = syncOperation;
@@ -1688,7 +1771,7 @@
                     new Comparator<RegisteredServicesCache.ServiceInfo<SyncAdapterType>>() {
                         @Override
                         public int compare(RegisteredServicesCache.ServiceInfo<SyncAdapterType> lhs,
-                                           RegisteredServicesCache.ServiceInfo<SyncAdapterType> rhs) {
+                                RegisteredServicesCache.ServiceInfo<SyncAdapterType> rhs) {
                             return lhs.type.authority.compareTo(rhs.type.authority);
                         }
                     });
@@ -2207,7 +2290,8 @@
             synchronized (this) {
                 if (!mBootCompleted || !mProvisioned) {
                     if (msg.what == MESSAGE_START_SYNC) {
-                        deferSyncH((SyncOperation) msg.obj, 60*1000 /* 1 minute */);
+                        SyncOperation op = (SyncOperation) msg.obj;
+                        addSyncOperationToCache(op);
                     }
                     // Need to copy the message bc looper will recycle it.
                     Message m = Message.obtain(msg);
@@ -2272,21 +2356,24 @@
 
                     case MESSAGE_STOP_SYNC:
                         op = (SyncOperation) msg.obj;
-                        boolean reschedule = msg.arg1 != 0;
-                        boolean applyBackoff = msg.arg2 != 0;
                         if (isLoggable) {
-                            Slog.v(TAG, "Stop sync received. Reschedule: " + reschedule
-                                    + "Backoff: " + applyBackoff);
-                        }
-                        if (applyBackoff) {
-                            increaseBackoffSetting(op.target);
-                        }
-                        if (reschedule) {
-                            scheduleSyncOperationH(op);
+                            Slog.v(TAG, "Stop sync received.");
                         }
                         ActiveSyncContext asc = findActiveSyncContextH(op.jobId);
                         if (asc != null) {
                             runSyncFinishedOrCanceledH(null /* no result */, asc);
+                            boolean reschedule = msg.arg1 != 0;
+                            boolean applyBackoff = msg.arg2 != 0;
+                            if (isLoggable) {
+                                Slog.v(TAG, "Stopping sync. Reschedule: " + reschedule
+                                        + "Backoff: " + applyBackoff);
+                            }
+                            if (applyBackoff) {
+                                increaseBackoffSetting(op.target);
+                            }
+                            if (reschedule) {
+                                deferStoppedSyncH(op, 0);
+                            }
                         }
                         break;
 
@@ -2414,7 +2501,8 @@
 
         /**
          * Defer the specified SyncOperation by rescheduling it on the JobScheduler with some
-         * delay.
+         * delay. This is equivalent to a failure. If this is a periodic sync, a delayed one-off
+         * sync will be scheduled.
          */
         private void deferSyncH(SyncOperation op, long delay) {
             mSyncJobService.callJobFinished(op.jobId, false);
@@ -2426,14 +2514,22 @@
             }
         }
 
+        /* Same as deferSyncH, but assumes that job is no longer running on JobScheduler. */
+        private void deferStoppedSyncH(SyncOperation op, long delay) {
+            if (op.isPeriodic) {
+                scheduleSyncOperationH(op.createOneTimeSyncOperation(), delay);
+            } else {
+                removeSyncOperationFromCache(op.jobId);
+                scheduleSyncOperationH(op, delay);
+            }
+        }
+
         /**
          * Cancel an active sync and reschedule it on the JobScheduler with some delay.
          */
         private void deferActiveSyncH(ActiveSyncContext asc) {
             SyncOperation op = asc.mSyncOperation;
-
-            mSyncHandler.obtainMessage(MESSAGE_STOP_SYNC, 0 /* no reschedule */,
-                    0 /* no backoff */, op).sendToTarget();
+            runSyncFinishedOrCanceledH(null, asc);
             deferSyncH(op, SYNC_DELAY_ON_CONFLICT);
         }
 
@@ -2467,6 +2563,7 @@
                 // Check for adapter delays.
                 if (isAdapterDelayed(op.target)) {
                     deferSyncH(op, 0 /* No minimum delay */);
+                    return;
                 }
             } else {
                 // Remove SyncOperation entry from mScheduledSyncs cache for non periodic jobs.
@@ -2489,6 +2586,7 @@
                             Slog.v(TAG, "Pushing back running sync due to a higher priority sync");
                         }
                         deferActiveSyncH(asc);
+                        break;
                     }
                 }
             }
@@ -2514,6 +2612,7 @@
         }
 
         private void updateRunningAccountsH(EndPoint syncTargets) {
+            AccountAndUser[] oldAccounts = mRunningAccounts;
             mRunningAccounts = AccountManagerService.getSingleton().getRunningAccounts();
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Slog.v(TAG, "Accounts list: ");
@@ -2537,6 +2636,17 @@
                 }
             }
 
+            // On account add, check if there are any settings to be restored.
+            for (AccountAndUser aau : mRunningAccounts) {
+                if (!containsAccountAndUser(oldAccounts, aau.account, aau.userId)) {
+                    if (Log.isLoggable(TAG, Log.DEBUG)) {
+                        Log.d(TAG, "Account " + aau.account + " added, checking sync restore data");
+                    }
+                    AccountSyncSettingsBackupHelper.accountAdded(mContext);
+                    break;
+                }
+            }
+
             List<SyncOperation> ops = getAllPendingSyncsFromCache();
             for (SyncOperation op: ops) {
                 if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) {
@@ -2560,22 +2670,22 @@
          * @param flexMillis new flex time in milliseconds.
          */
         private void maybeUpdateSyncPeriodH(SyncOperation syncOperation, long pollFrequencyMillis,
-                                            long flexMillis) {
+                long flexMillis) {
             if (!(pollFrequencyMillis == syncOperation.periodMillis
                     && flexMillis == syncOperation.flexMillis)) {
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Slog.v(TAG, "updating period " + syncOperation + " to " + pollFrequencyMillis
                             + " and flex to " + flexMillis);
                 }
-                removePeriodicSyncInternalH(syncOperation);
-                syncOperation.periodMillis = pollFrequencyMillis;
-                syncOperation.flexMillis = flexMillis;
-                scheduleSyncOperationH(syncOperation);
+                SyncOperation newOp = new SyncOperation(syncOperation, pollFrequencyMillis,
+                        flexMillis);
+                newOp.jobId = syncOperation.jobId;
+                scheduleSyncOperationH(newOp);
             }
         }
 
         private void updateOrAddPeriodicSyncH(EndPoint target, long pollFrequency, long flex,
-                                              Bundle extras) {
+                Bundle extras) {
             final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
             verifyJobScheduler();  // Will fill in mScheduledSyncs cache if it is not already filled.
             final long pollFrequencyMillis = pollFrequency * 1000L;
@@ -2614,9 +2724,8 @@
             SyncOperation op = new SyncOperation(target, syncAdapterInfo.uid,
                     syncAdapterInfo.componentName.getPackageName(), SyncOperation.REASON_PERIODIC,
                     SyncStorageEngine.SOURCE_PERIODIC, extras,
-                    syncAdapterInfo.type.allowParallelSyncs(), true, SyncOperation.NO_JOB_ID);
-            op.periodMillis = pollFrequencyMillis;
-            op.flexMillis = flexMillis;
+                    syncAdapterInfo.type.allowParallelSyncs(), true, SyncOperation.NO_JOB_ID,
+                    pollFrequencyMillis, flexMillis);
             scheduleSyncOperationH(op);
             mSyncStorageEngine.reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         }
@@ -2764,7 +2873,7 @@
         }
 
         private void runBoundToAdapterH(final ActiveSyncContext activeSyncContext,
-                                        IBinder syncAdapter) {
+                IBinder syncAdapter) {
             final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
             try {
                 activeSyncContext.mIsLinkedToDeath = true;
@@ -2816,14 +2925,23 @@
          * Should be called when a one-off instance of a periodic sync completes successfully.
          */
         private void reschedulePeriodicSyncH(SyncOperation syncOperation) {
-            removeSyncOperationFromCache(syncOperation.sourcePeriodicId);
-            getJobScheduler().cancel(syncOperation.sourcePeriodicId);
-            SyncOperation periodic = syncOperation.createPeriodicSyncOperation();
-            scheduleSyncOperationH(periodic);
+            // Ensure that the periodic sync wasn't removed.
+            SyncOperation periodicSync = null;
+            List<SyncOperation> ops = getAllPendingSyncsFromCache();
+            for (SyncOperation op: ops) {
+                if (op.isPeriodic && syncOperation.matchesPeriodicOperation(op)) {
+                    periodicSync = op;
+                    break;
+                }
+            }
+            if (periodicSync == null) {
+                return;
+            }
+            scheduleSyncOperationH(periodicSync);
         }
 
         private void runSyncFinishedOrCanceledH(SyncResult syncResult,
-                                                ActiveSyncContext activeSyncContext) {
+                ActiveSyncContext activeSyncContext) {
             final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
             final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
@@ -2957,7 +3075,7 @@
         }
 
         private void installHandleTooManyDeletesNotification(Account account, String authority,
-                                                             long numDeletes, int userId) {
+                long numDeletes, int userId) {
             if (mNotificationMgr == null) return;
 
             final ProviderInfo providerInfo = mContext.getPackageManager().resolveContentProvider(
@@ -3033,7 +3151,7 @@
         }
 
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
-                                  int upstreamActivity, int downstreamActivity, long elapsedTime) {
+                int upstreamActivity, int downstreamActivity, long elapsedTime) {
             EventLog.writeEvent(2720,
                     syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
@@ -3197,4 +3315,4 @@
             return mContext;
         }
     }
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index 4fb31c0..957b087 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -79,9 +79,9 @@
     public final String key;
 
     /** Poll frequency of periodic sync in milliseconds */
-    public long periodMillis;
+    public final long periodMillis;
     /** Flex time of periodic sync in milliseconds */
-    public long flexMillis;
+    public final long flexMillis;
     /** Descriptive string key for this operation */
     public String wakeLockName;
     /**
@@ -90,6 +90,9 @@
      */
     public long expectedRuntime;
 
+    /** Stores the number of times this sync operation failed and had to be retried. */
+    int retries;
+
     /** jobId of the JobScheduler job corresponding to this sync */
     public int jobId;
 
@@ -103,23 +106,32 @@
     private SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage,
                           int reason, int source, Bundle extras, boolean allowParallelSyncs) {
         this(info, owningUid, owningPackage, reason, source, extras, allowParallelSyncs, false,
-                NO_JOB_ID);
+                NO_JOB_ID, 0, 0);
+    }
+
+    public SyncOperation(SyncOperation op, long periodMillis, long flexMillis) {
+        this(op.target, op.owningUid, op.owningPackage, op.reason, op.syncSource,
+                new Bundle(op.extras), op.allowParallelSyncs, op.isPeriodic, op.sourcePeriodicId,
+                periodMillis, flexMillis);
     }
 
     public SyncOperation(SyncStorageEngine.EndPoint info, int owningUid, String owningPackage,
                          int reason, int source, Bundle extras, boolean allowParallelSyncs,
-                         boolean isPeriodic, int sourcePeriodicId) {
+                         boolean isPeriodic, int sourcePeriodicId, long periodMillis,
+                         long flexMillis) {
         this.target = info;
         this.owningUid = owningUid;
         this.owningPackage = owningPackage;
         this.reason = reason;
         this.syncSource = source;
         this.extras = new Bundle(extras);
-        cleanBundle(this.extras);
         this.allowParallelSyncs = allowParallelSyncs;
         this.isPeriodic = isPeriodic;
         this.sourcePeriodicId = sourcePeriodicId;
-        this.key = toKey(target, extras);
+        this.periodMillis = periodMillis;
+        this.flexMillis = flexMillis;
+        this.jobId = NO_JOB_ID;
+        this.key = toKey();
     }
 
     /* Get a one off sync operation instance from a periodic sync. */
@@ -128,18 +140,8 @@
             return null;
         }
         SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, syncSource,
-                new Bundle(extras), allowParallelSyncs, false, jobId /* sourcePeriodicId */);
-        // Copied to help us recreate the periodic sync from this one off sync.
-        op.periodMillis = periodMillis;
-        op.flexMillis = flexMillis;
-        return op;
-    }
-
-    public SyncOperation createPeriodicSyncOperation() {
-        SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, syncSource,
-                new Bundle(extras), allowParallelSyncs, true, NO_JOB_ID);
-        op.periodMillis = periodMillis;
-        op.flexMillis = flexMillis;
+                new Bundle(extras), allowParallelSyncs, false, jobId /* sourcePeriodicId */,
+                periodMillis, flexMillis);
         return op;
     }
 
@@ -224,6 +226,7 @@
         jobInfoExtras.putLong("periodMillis", periodMillis);
         jobInfoExtras.putLong("flexMillis", flexMillis);
         jobInfoExtras.putLong("expectedRuntime", expectedRuntime);
+        jobInfoExtras.putInt("retries", retries);
         return jobInfoExtras;
     }
 
@@ -240,6 +243,7 @@
         int initiatedBy;
         Bundle extras;
         boolean allowParallelSyncs, isPeriodic;
+        long periodMillis, flexMillis;
 
         if (!jobExtras.getBoolean("SyncManagerJob", false)) {
             return null;
@@ -256,6 +260,8 @@
         allowParallelSyncs = jobExtras.getBoolean("allowParallelSyncs", false);
         isPeriodic = jobExtras.getBoolean("isPeriodic", false);
         initiatedBy = jobExtras.getInt("sourcePeriodicId", NO_JOB_ID);
+        periodMillis = jobExtras.getLong("periodMillis");
+        flexMillis = jobExtras.getLong("flexMillis");
         extras = new Bundle();
 
         PersistableBundle syncExtras = jobExtras.getPersistableBundle("syncExtras");
@@ -277,38 +283,14 @@
         SyncStorageEngine.EndPoint target =
                 new SyncStorageEngine.EndPoint(account, provider, userId);
         SyncOperation op = new SyncOperation(target, owningUid, owningPackage, reason, source,
-                extras, allowParallelSyncs, isPeriodic, initiatedBy);
+                extras, allowParallelSyncs, isPeriodic, initiatedBy, periodMillis, flexMillis);
         op.jobId = jobExtras.getInt("jobId");
-        op.periodMillis = jobExtras.getLong("periodMillis");
-        op.flexMillis = jobExtras.getLong("flexMillis");
         op.expectedRuntime = jobExtras.getLong("expectedRuntime");
+        op.retries = jobExtras.getInt("retries");
         return op;
     }
 
     /**
-     * Make sure the bundle attached to this SyncOperation doesn't have unnecessary
-     * flags set.
-     * @param bundle to clean.
-     */
-    private void cleanBundle(Bundle bundle) {
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_UPLOAD);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_MANUAL);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_EXPEDITED);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS);
-        removeFalseExtra(bundle, ContentResolver.SYNC_EXTRAS_DISALLOW_METERED);
-    }
-
-    private void removeFalseExtra(Bundle bundle, String extraName) {
-        if (!bundle.getBoolean(extraName, false)) {
-            bundle.remove(extraName);
-        }
-    }
-
-    /**
      * Determine whether if this sync operation is running, the provided operation would conflict
      * with it.
      * Parallel syncs allow multiple accounts to be synced at the same time.
@@ -326,6 +308,12 @@
         return reason == REASON_PERIODIC;
     }
 
+    boolean matchesPeriodicOperation(SyncOperation other) {
+        return target.matchesSpec(other.target)
+                && SyncManager.syncExtrasEquals(extras, other.extras, true)
+                && periodMillis == other.periodMillis && flexMillis == other.flexMillis;
+    }
+
     boolean isDerivedFromFailedPeriodicSync() {
         return sourcePeriodicId != NO_JOB_ID;
     }
@@ -339,15 +327,18 @@
         return 0;
     }
 
-    static String toKey(SyncStorageEngine.EndPoint info, Bundle extras) {
+    private String toKey() {
         StringBuilder sb = new StringBuilder();
-        sb.append("provider: ").append(info.provider);
-        sb.append(" account {name=" + info.account.name
+        sb.append("provider: ").append(target.provider);
+        sb.append(" account {name=" + target.account.name
                 + ", user="
-                + info.userId
+                + target.userId
                 + ", type="
-                + info.account.type
+                + target.account.type
                 + "}");
+        sb.append(" isPeriodic: ").append(isPeriodic);
+        sb.append(" period: ").append(periodMillis);
+        sb.append(" flex: ").append(flexMillis);
         sb.append(" extras: ");
         extrasToStringBuilder(extras, sb);
         return sb.toString();
@@ -360,7 +351,9 @@
 
     String dump(PackageManager pm, boolean useOneLine) {
         StringBuilder sb = new StringBuilder();
-        sb.append(target.account.name)
+        sb.append("JobId: ").append(jobId)
+                .append(", ")
+                .append(target.account.name)
                 .append(" u")
                 .append(target.userId).append(" (")
                 .append(target.account.type)
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f8e3e48..cefaa8d 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -80,7 +80,7 @@
     private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles";
 
     /** Default time for a periodic sync. */
-    private static final long DEFAULT_POLL_FREQUENCY_SECONDS = 60 * 60 * 24; // One day
+    static final long DEFAULT_POLL_FREQUENCY_SECONDS = 60 * 60 * 24; // One day
 
     /** Percentage of period that is flex by default, if no flexMillis is set. */
     private static final double DEFAULT_FLEX_PERCENT_SYNC = 0.04;
@@ -438,9 +438,7 @@
         if (sSyncStorageEngine != null) {
             return;
         }
-        // This call will return the correct directory whether Encrypted File Systems is
-        // enabled or not.
-        File dataDir = Environment.getSecureDataDirectory();
+        File dataDir = Environment.getDataDirectory();
         sSyncStorageEngine = new SyncStorageEngine(context, dataDir);
     }
 
@@ -859,6 +857,16 @@
         }
     }
 
+    List<AuthorityInfo> getAllAuthorities() {
+        List<AuthorityInfo> authorities = new ArrayList<AuthorityInfo>();
+        synchronized (mAuthorities) {
+            for (int i = 0; i < mAuthorities.size(); i++) {
+                authorities.add(mAuthorities.valueAt(i));
+            }
+        }
+        return authorities;
+    }
+
     /**
      * Returns true if there is currently a sync operation being actively processed for the given
      * target.
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index b74b0f2..1038d97 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -840,7 +840,11 @@
         // If there is already an animation in progress, don't interfere with it.
         if (mColorFadeOnAnimator.isStarted()
                 || mColorFadeOffAnimator.isStarted()) {
-            return;
+            if (target != Display.STATE_ON) {
+                return;
+            }
+            // If display state changed to on, proceed and stop the color fade and turn screen on.
+            mPendingScreenOff = false;
         }
 
         // If we were in the process of turning off the screen but didn't quite
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index 62114cd..7e19c66 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -52,7 +52,7 @@
     static final String TAG = "IntentFirewall";
 
     // e.g. /data/system/ifw or /data/secure/system/ifw
-    private static final File RULES_DIR = new File(Environment.getSystemSecureDirectory(), "ifw");
+    private static final File RULES_DIR = new File(Environment.getDataSystemDirectory(), "ifw");
 
     private static final int LOG_PACKAGES_MAX_LENGTH = 150;
     private static final int LOG_PACKAGES_SUFFICIENT_LENGTH = 125;
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 4c269989..57cede8 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -231,10 +231,7 @@
     }
 
     public int scheduleAsPackage(JobInfo job, int uId, String packageName, int userId) {
-        JobStatus jobStatus = new JobStatus(job, uId);
-        if (packageName != null) {
-            jobStatus.setSource(packageName, userId);
-        }
+        JobStatus jobStatus = new JobStatus(job, uId, packageName, userId);
         try {
             if (ActivityManagerNative.getDefault().getAppStartMode(uId,
                     job.getService().getPackageName()) == ActivityManager.APP_START_MODE_DISABLED) {
@@ -330,7 +327,7 @@
 
     private void cancelJobImpl(JobStatus cancelled) {
         if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
-        stopTrackingJob(cancelled);
+        stopTrackingJob(cancelled, true /* writeBack */);
         synchronized (mJobs) {
             // Remove from pending queue.
             mPendingJobs.remove(cancelled);
@@ -509,12 +506,12 @@
      * Called when we want to remove a JobStatus object that we've finished executing. Returns the
      * object removed.
      */
-    private boolean stopTrackingJob(JobStatus jobStatus) {
+    private boolean stopTrackingJob(JobStatus jobStatus, boolean writeBack) {
         boolean removed;
         boolean rocking;
         synchronized (mJobs) {
             // Remove from store as well as controllers.
-            removed = mJobs.remove(jobStatus);
+            removed = mJobs.remove(jobStatus, writeBack);
             rocking = mReadyToRock;
         }
         if (removed && rocking) {
@@ -645,7 +642,9 @@
         if (DEBUG) {
             Slog.d(TAG, "Completed " + jobStatus + ", reschedule=" + needsReschedule);
         }
-        if (!stopTrackingJob(jobStatus)) {
+        // Do not write back immediately if this is a periodic job. The job may get lost if system
+        // shuts down before it is added back.
+        if (!stopTrackingJob(jobStatus, !jobStatus.getJob().isPeriodic())) {
             if (DEBUG) {
                 Slog.d(TAG, "Could not find job to remove. Was job removed while executing?");
             }
@@ -1024,7 +1023,8 @@
             final IPackageManager pm = AppGlobals.getPackageManager();
             final ComponentName service = job.getService();
             try {
-                ServiceInfo si = pm.getServiceInfo(service, 0, UserHandle.getUserId(uid));
+                ServiceInfo si = pm.getServiceInfo(service,
+                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(uid));
                 if (si == null) {
                     throw new IllegalArgumentException("No such service " + service);
                 }
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index f796164..3565fc1 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -159,9 +159,10 @@
 
     /**
      * Remove the provided job. Will also delete the job if it was persisted.
+     * @param writeBack If true, the job will be deleted (if it was persisted) immediately.
      * @return Whether or not the job existed to be removed.
      */
-    public boolean remove(JobStatus jobStatus) {
+    public boolean remove(JobStatus jobStatus, boolean writeBack) {
         boolean removed = mJobSet.remove(jobStatus);
         if (!removed) {
             if (DEBUG) {
@@ -169,7 +170,7 @@
             }
             return false;
         }
-        if (jobStatus.isPersisted()) {
+        if (writeBack && jobStatus.isPersisted()) {
             maybeWriteStatusToDiskAsync();
         }
         return removed;
@@ -281,8 +282,7 @@
                         continue;
                     }
 
-                    JobStatus copy = new JobStatus(jobStatus.getJob(), jobStatus.getUid(),
-                            jobStatus.getEarliestRunTime(), jobStatus.getLatestRunTimeElapsed());
+                    JobStatus copy = new JobStatus(jobStatus);
                     mStoreCopy.add(copy);
                 }
             }
@@ -543,7 +543,7 @@
         private JobStatus restoreJobFromXml(XmlPullParser parser) throws XmlPullParserException,
                 IOException {
             JobInfo.Builder jobBuilder;
-            int uid, userId;
+            int uid, sourceUserId;
 
             // Read out job identifier attributes and priority.
             try {
@@ -556,7 +556,7 @@
                     jobBuilder.setPriority(Integer.valueOf(val));
                 }
                 val = parser.getAttributeValue(null, "sourceUserId");
-                userId = val == null ? -1 : Integer.valueOf(val);
+                sourceUserId = val == null ? -1 : Integer.valueOf(val);
             } catch (NumberFormatException e) {
                 Slog.e(TAG, "Error parsing job's required fields, skipping");
                 return null;
@@ -607,9 +607,9 @@
                 try {
                     String val = parser.getAttributeValue(null, "period");
                     final long periodMillis = Long.valueOf(val);
-                    jobBuilder.setPeriodic(periodMillis);
                     val = parser.getAttributeValue(null, "flex");
                     final long flexMillis = (val != null) ? Long.valueOf(val) : periodMillis;
+                    jobBuilder.setPeriodic(periodMillis, flexMillis);
                     // As a sanity check, cap the recreated run time to be no later than flex+period
                     // from now. This is the latest the periodic could be pushed out. This could
                     // happen if the periodic ran early (at flex time before period), and then the
@@ -678,10 +678,8 @@
             parser.nextTag(); // Consume </extras>
 
             JobStatus js = new JobStatus(
-                    jobBuilder.build(), uid, elapsedRuntimes.first, elapsedRuntimes.second);
-            if (userId != -1) {
-                js.setSource(sourcePackageName, userId);
-            }
+                    jobBuilder.build(), uid, sourcePackageName, sourceUserId, elapsedRuntimes.first,
+                    elapsedRuntimes.second);
             return js;
         }
 
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index e749433..c4d564c 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -48,13 +48,13 @@
 
     final JobInfo job;
     /** Uid of the package requesting this job. */
-    final int uId;
+    final int callingUid;
     final String name;
     final String tag;
 
-    String sourcePackageName;
-    int sourceUserId = -1;
-    int sourceUid = -1;
+    final String sourcePackageName;
+    final int sourceUserId;
+    final int sourceUid;
 
     // Constraints.
     final AtomicBoolean chargingConstraintSatisfied = new AtomicBoolean();
@@ -91,30 +91,55 @@
 
     /** Provide a handle to the service that this job will be run on. */
     public int getServiceToken() {
-        return uId;
+        return callingUid;
     }
 
-    private JobStatus(JobInfo job, int uId, int numFailures) {
+    private JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
+                      int numFailures) {
         this.job = job;
-        this.uId = uId;
-        this.sourceUid = uId;
+        this.callingUid = callingUid;
         this.name = job.getService().flattenToShortString();
         this.tag = "*job*/" + this.name;
         this.numFailures = numFailures;
+
+        int tempSourceUid = -1;
+        if (sourceUserId != -1 && sourcePackageName != null) {
+            try {
+                tempSourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0,
+                        sourceUserId);
+            } catch (RemoteException ex) {
+                // Can't happen, PackageManager runs in the same process.
+            }
+        }
+        if (tempSourceUid == -1) {
+            this.sourceUid = callingUid;
+            this.sourceUserId = UserHandle.getUserId(callingUid);
+            this.sourcePackageName = job.getService().getPackageName();
+        } else {
+            this.sourceUid = tempSourceUid;
+            this.sourceUserId = sourceUserId;
+            this.sourcePackageName = sourcePackageName;
+        }
     }
 
     /** Copy constructor. */
     public JobStatus(JobStatus jobStatus) {
-        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getNumFailures());
-        this.sourceUserId = jobStatus.sourceUserId;
-        this.sourcePackageName = jobStatus.sourcePackageName;
+        this(jobStatus.getJob(), jobStatus.getUid(), jobStatus.getSourcePackageName(),
+                jobStatus.getSourceUserId(), jobStatus.getNumFailures());
         this.earliestRunTimeElapsedMillis = jobStatus.getEarliestRunTime();
         this.latestRunTimeElapsedMillis = jobStatus.getLatestRunTimeElapsed();
     }
 
-    /** Create a newly scheduled job. */
-    public JobStatus(JobInfo job, int uId) {
-        this(job, uId, 0);
+    /**
+     * Create a newly scheduled job.
+     * @param callingUid Uid of the package that scheduled this job.
+     * @param sourcePackageName Package name on whose behalf this job is scheduled. Null indicates
+     *                          the calling package is the source.
+     * @param sourceUserId User id for whom this job is scheduled. -1 indicates this is same as the
+     *                     calling userId.
+     */
+    public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId) {
+        this(job, callingUid, sourcePackageName, sourceUserId, 0);
 
         final long elapsedNow = SystemClock.elapsedRealtime();
 
@@ -136,9 +161,9 @@
      * wallclock runtime rather than resetting it on every boot.
      * We consider a freshly loaded job to no longer be in back-off.
      */
-    public JobStatus(JobInfo job, int uId, long earliestRunTimeElapsedMillis,
-                      long latestRunTimeElapsedMillis) {
-        this(job, uId, 0);
+    public JobStatus(JobInfo job, int callingUid, String sourcePackageName, int sourceUserId,
+                     long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) {
+        this(job, callingUid, sourcePackageName, sourceUserId, 0);
 
         this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis;
         this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis;
@@ -147,9 +172,8 @@
     /** Create a new job to be rescheduled with the provided parameters. */
     public JobStatus(JobStatus rescheduling, long newEarliestRuntimeElapsedMillis,
                       long newLatestRuntimeElapsedMillis, int backoffAttempt) {
-        this(rescheduling.job, rescheduling.getUid(), backoffAttempt);
-        this.sourceUserId = rescheduling.sourceUserId;
-        this.sourcePackageName = rescheduling.sourcePackageName;
+        this(rescheduling.job, rescheduling.getUid(), rescheduling.getSourcePackageName(),
+                rescheduling.getSourceUserId(), backoffAttempt);
 
         earliestRunTimeElapsedMillis = newEarliestRuntimeElapsedMillis;
         latestRunTimeElapsedMillis = newLatestRuntimeElapsedMillis;
@@ -172,7 +196,7 @@
     }
 
     public String getSourcePackageName() {
-        return sourcePackageName != null ? sourcePackageName : job.getService().getPackageName();
+        return sourcePackageName;
     }
 
     public int getSourceUid() {
@@ -180,18 +204,15 @@
     }
 
     public int getSourceUserId() {
-        if (sourceUserId == -1) {
-            sourceUserId = getUserId();
-        }
         return sourceUserId;
     }
 
     public int getUserId() {
-        return UserHandle.getUserId(uId);
+        return UserHandle.getUserId(callingUid);
     }
 
     public int getUid() {
-        return uId;
+        return callingUid;
     }
 
     public String getName() {
@@ -278,7 +299,7 @@
     }
 
     public boolean matches(int uid, int jobId) {
-        return this.job.getId() == jobId && this.uId == uid;
+        return this.job.getId() == jobId && this.callingUid == uid;
     }
 
     @Override
@@ -312,22 +333,6 @@
         }
     }
 
-    public void setSource(String sourcePackageName, int sourceUserId) {
-        this.sourcePackageName = sourcePackageName;
-        this.sourceUserId = sourceUserId;
-        try {
-            sourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0,
-                    sourceUserId);
-        } catch (RemoteException ex) {
-            // Can't happen, PackageManager runs in the same process.
-        }
-        if (sourceUid == -1) {
-            sourceUid = uId;
-            this.sourceUserId = getUserId();
-            this.sourcePackageName = null;
-        }
-    }
-
     /**
      * Convenience function to identify a job uniquely without pulling all the data that
      * {@link #toString()} returns.
@@ -338,7 +343,7 @@
         sb.append(" jId=");
         sb.append(job.getId());
         sb.append(" uid=");
-        UserHandle.formatUid(sb, uId);
+        UserHandle.formatUid(sb, callingUid);
         sb.append(' ');
         sb.append(job.getService().flattenToShortString());
         return sb.toString();
@@ -346,7 +351,7 @@
 
     // Dumpsys infrastructure
     public void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); UserHandle.formatUid(pw, uId);
+        pw.print(prefix); UserHandle.formatUid(pw, callingUid);
         pw.print(" tag="); pw.println(tag);
         pw.print(prefix);
         pw.print("Source: uid="); UserHandle.formatUid(pw, getSourceUid());
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index ffc52b3..c1eb844 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1557,15 +1557,13 @@
      * called from native code to update SV info
      */
     private void reportSvStatus() {
-        int svCount = native_read_sv_status(mPrnWithFlags, mSnrs, mSvElevations, mSvAzimuths,
-                mConstellationTypes);
+        int svCount = native_read_sv_status(mSvidWithFlags, mSnrs, mSvElevations, mSvAzimuths);
         mListenerHelper.onSvStatusChanged(
                 svCount,
-                mPrnWithFlags,
+                mSvidWithFlags,
                 mSnrs,
                 mSvElevations,
-                mSvAzimuths,
-                mConstellationTypes);
+                mSvAzimuths);
 
         if (VERBOSE) {
             Log.v(TAG, "SV count: " + svCount);
@@ -1573,19 +1571,19 @@
         // Calculate number of sets used in fix.
         int usedInFixCount = 0;
         for (int i = 0; i < svCount; i++) {
-            if ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
+            if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
                 ++usedInFixCount;
             }
             if (VERBOSE) {
-                Log.v(TAG, "prn: " + (mPrnWithFlags[i] >> GnssStatus.PRN_SHIFT_WIDTH) +
+                Log.v(TAG, "svid: " + (mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
                         " snr: " + mSnrs[i]/10 +
                         " elev: " + mSvElevations[i] +
                         " azimuth: " + mSvAzimuths[i] +
-                        ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
+                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
                                 ? "  " : " E") +
-                        ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
+                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
                                 ? "  " : " A") +
-                        ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
+                        ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
                                 ? "" : "U"));
             }
         }
@@ -2398,14 +2396,13 @@
     }
 
     // for GPS SV statistics
-    private static final int MAX_SVS = 512;
+    private static final int MAX_SVS = 64;
 
     // preallocated arrays, to avoid memory allocation in reportStatus()
-    private int mPrnWithFlags[] = new int[MAX_SVS];
+    private int mSvidWithFlags[] = new int[MAX_SVS];
     private float mSnrs[] = new float[MAX_SVS];
     private float mSvElevations[] = new float[MAX_SVS];
     private float mSvAzimuths[] = new float[MAX_SVS];
-    private int mConstellationTypes[] = new int[MAX_SVS];
     private int mSvCount;
     // preallocated to avoid memory allocation in reportNmea()
     private byte[] mNmeaBuffer = new byte[120];
@@ -2426,7 +2423,7 @@
     // returns number of SVs
     // mask[0] is ephemeris mask and mask[1] is almanac mask
     private native int native_read_sv_status(int[] prnWithFlags, float[] snrs, float[] elevations,
-            float[] azimuths, int[] constellationTypes);
+            float[] azimuths);
     private native int native_read_nmea(byte[] buffer, int bufferSize);
     private native void native_inject_location(double latitude, double longitude, float accuracy);
 
diff --git a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
index 9840c61..0b3111c 100644
--- a/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
+++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java
@@ -77,8 +77,7 @@
             final int[] prnWithFlags,
             final float[] snrs,
             final float[] elevations,
-            final float[] azimuths,
-            final int[] constellationTypes) {
+            final float[] azimuths) {
         Operation operation = new Operation() {
             @Override
             public void execute(IGnssStatusListener listener) throws RemoteException {
@@ -87,8 +86,7 @@
                         prnWithFlags,
                         snrs,
                         elevations,
-                        azimuths,
-                        constellationTypes);
+                        azimuths);
             }
         };
         foreach(operation);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 7f8099e..bc5b561 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -339,6 +339,8 @@
     private final AppOpsManager mAppOps;
 
     private final MyPackageMonitor mPackageMonitor;
+    private final IPackageManager mIPm;
+
 
     // TODO: keep whitelist of system-critical services that should never have
     // rules enforced, such as system, phone, and radio UIDs.
@@ -369,6 +371,7 @@
                 Context.DEVICE_IDLE_CONTROLLER));
         mTime = checkNotNull(time, "missing TrustedTime");
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mIPm = AppGlobals.getPackageManager();
 
         HandlerThread thread = new HandlerThread(TAG);
         thread.start();
@@ -760,9 +763,7 @@
                 if (policy == null && meteredHint) {
                     // policy doesn't exist, and AP is hinting that it's
                     // metered: create an inferred policy.
-                    policy = new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
-                            WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
-                            meteredHint, true);
+                    policy = newWifiPolicy(template, meteredHint);
                     addNetworkPolicyLocked(policy);
 
                 } else if (policy != null && policy.inferred) {
@@ -778,6 +779,12 @@
         }
     };
 
+    static NetworkPolicy newWifiPolicy(NetworkTemplate template, boolean metered) {
+        return new NetworkPolicy(template, CYCLE_NONE, Time.TIMEZONE_UTC,
+                WARNING_DISABLED, LIMIT_DISABLED, SNOOZE_NEVER, SNOOZE_NEVER,
+                metered, true);
+    }
+
     /**
      * Observer that watches for {@link INetworkManagementService} alerts.
      */
@@ -1860,31 +1867,58 @@
     @Override
     public void addRestrictBackgroundWhitelistedUid(int uid) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-        Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist");
+        if (!isUidValidForRules(uid)) return;
+        final boolean changed;
         synchronized (mRulesLock) {
+            final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
+            if (oldStatus) {
+                if (LOGD) Slog.d(TAG, "uid " + uid + " is already whitelisted");
+                return;
+            }
+            Slog.i(TAG, "adding uid " + uid + " to restrict background whitelist");
             mRestrictBackgroundWhitelistUids.append(uid, true);
-            updateRulesForGlobalChangeLocked(true);
+            changed = mRestrictBackground && !oldStatus;
+            if (changed && hasInternetPermissions(uid)) {
+                setUidNetworkRules(uid, false);
+            }
             writePolicyLocked();
         }
-        mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 0).sendToTarget();
+        if (changed) {
+            mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 0)
+                    .sendToTarget();
+        }
     }
 
     @Override
     public void removeRestrictBackgroundWhitelistedUid(int uid) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-        Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist");
+        if (!isUidValidForRules(uid)) return;
+        final boolean changed;
         synchronized (mRulesLock) {
-            removeRestrictBackgroundWhitelistedUidLocked(uid, true);
+            changed = removeRestrictBackgroundWhitelistedUidLocked(uid, true);
         }
-        mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 0).sendToTarget();
+        if (changed) {
+            mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_WHITELIST_CHANGED, uid, 0)
+                    .sendToTarget();
+        }
     }
 
-    private void removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean updateNow) {
+    private boolean removeRestrictBackgroundWhitelistedUidLocked(int uid, boolean updateNow) {
+        final boolean oldStatus = mRestrictBackgroundWhitelistUids.get(uid);
+        if (!oldStatus) {
+            if (LOGD) Slog.d(TAG, "uid " + uid + " was not whitelisted before");
+            return false;
+        }
+        Slog.i(TAG, "removing uid " + uid + " from restrict background whitelist");
+        final boolean changed = mRestrictBackground && oldStatus;
         mRestrictBackgroundWhitelistUids.delete(uid);
         if (updateNow) {
-            updateRulesForGlobalChangeLocked(true);
+            if (changed && hasInternetPermissions(uid)) {
+                setUidNetworkRules(uid, true);
+            }
             writePolicyLocked();
         }
+        return changed;
     }
 
     @Override
@@ -2154,7 +2188,7 @@
     @Override
     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
             String[] args, ResultReceiver resultReceiver) throws RemoteException {
-        (new NetworkPolicyManagerShellCommand(this)).exec(
+        (new NetworkPolicyManagerShellCommand(mContext, this)).exec(
                 this, in, out, err, args, resultReceiver);
     }
 
@@ -2294,13 +2328,19 @@
         uidRules.clear();
 
         // Fully update the app idle firewall chain.
+        final IPackageManager ipm = AppGlobals.getPackageManager();
         final List<UserInfo> users = mUserManager.getUsers();
         for (int ui = users.size() - 1; ui >= 0; ui--) {
             UserInfo user = users.get(ui);
             int[] idleUids = mUsageStats.getIdleUidsForUser(user.id);
             for (int uid : idleUids) {
                 if (!mPowerSaveTempWhitelistAppIds.get(UserHandle.getAppId(uid), false)) {
-                    uidRules.put(uid, FIREWALL_RULE_DENY);
+                    // quick check: if this uid doesn't have INTERNET permission, it
+                    // doesn't have network access anyway, so it is a waste to mess
+                    // with it here.
+                    if (hasInternetPermissions(uid)) {
+                        uidRules.put(uid, FIREWALL_RULE_DENY);
+                    }
                 }
             }
         }
@@ -2404,22 +2444,27 @@
     }
 
     /**
+     * Checks if an uid has INTERNET permissions.
+     * <p>
+     * Useful for the cases where the lack of network access can simplify the rules.
+     */
+    private boolean hasInternetPermissions(int uid) {
+        try {
+            if (mIPm.checkUidPermission(Manifest.permission.INTERNET, uid)
+                    != PackageManager.PERMISSION_GRANTED) {
+                return false;
+            }
+        } catch (RemoteException e) {
+        }
+        return true;
+    }
+
+    /**
      * Applies network rules to bandwidth and firewall controllers based on uid policy.
      * @param uid The uid for which to apply the latest policy
      */
     void updateRulesForUidLocked(int uid) {
-        if (!isUidValidForRules(uid)) return;
-
-        // quick check: if this uid doesn't have INTERNET permission, it doesn't have
-        // network access anyway, so it is a waste to mess with it here.
-        final IPackageManager ipm = AppGlobals.getPackageManager();
-        try {
-            if (ipm.checkUidPermission(Manifest.permission.INTERNET, uid)
-                    != PackageManager.PERMISSION_GRANTED) {
-                return;
-            }
-        } catch (RemoteException e) {
-        }
+        if (!isUidValidForRules(uid) || !hasInternetPermissions(uid)) return;
 
         final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
         final boolean uidForeground = isUidForegroundLocked(uid);
@@ -2586,15 +2631,18 @@
                     final int uid = msg.arg1;
                     final PackageManager pm = mContext.getPackageManager();
                     final String[] packages = pm.getPackagesForUid(uid);
-                    final int userId = UserHandle.getUserId(uid);
-                    for (String packageName : packages) {
-                        final Intent intent =
-                                new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
-                        intent.setPackage(packageName);
-                        intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-                        mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+                    if (packages != null) {
+                        final int userId = UserHandle.getUserId(uid);
+                        for (String packageName : packages) {
+                            final Intent intent = new Intent(
+                                    ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
+                            intent.setPackage(packageName);
+                            intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                            mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+                        }
+                    } else {
+                        Slog.w(TAG, "no packages for uid " + uid);
                     }
-
                     return true;
                 }
                 case MSG_ADVISE_PERSIST_THRESHOLD: {
@@ -2827,13 +2875,5 @@
                 removeRestrictBackgroundWhitelistedUidLocked(uid, true);
             }
         }
-
-        @Override
-        public void onPackageRemovedAllUsers(String packageName, int uid) {
-            if (LOGV) Slog.v(TAG, "onPackageRemovedAllUsers: " + packageName + " ->" + uid);
-            synchronized (mRulesLock) {
-                removeRestrictBackgroundWhitelistedUidLocked(uid, true);
-            }
-        }
     }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
index 281c3d0..5cd1025 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
@@ -16,14 +16,22 @@
 
 package com.android.server.net;
 
+import static android.net.wifi.WifiInfo.removeDoubleQuotes;
+import static com.android.server.net.NetworkPolicyManagerService.newWifiPolicy;
 import static com.android.server.net.NetworkPolicyManagerService.TAG;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import android.content.Context;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkPolicy;
+import android.net.NetworkTemplate;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ShellCommand;
@@ -31,10 +39,12 @@
 
 class NetworkPolicyManagerShellCommand extends ShellCommand {
 
-    final INetworkPolicyManager mInterface;
+    private final INetworkPolicyManager mInterface;
+    private final WifiManager mWifiManager;
 
-    NetworkPolicyManagerShellCommand(INetworkPolicyManager service) {
+    NetworkPolicyManagerShellCommand(Context context, INetworkPolicyManager service) {
         mInterface = service;
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     }
 
     @Override
@@ -100,7 +110,7 @@
         }
         switch(type) {
             case "metered-network":
-                return getNonMobileMeteredNetwork();
+                return getMeteredWifiNetwork();
             case "restrict-background":
                 return getRestrictBackground();
         }
@@ -117,7 +127,7 @@
         }
         switch(type) {
             case "metered-network":
-                return setNonMobileMeteredNetwork();
+                return setMeteredWifiNetwork();
             case "restrict-background":
                 return setRestrictBackground();
         }
@@ -134,9 +144,9 @@
         }
         switch(type) {
             case "metered-networks":
-                return listNonMobileMeteredNetworks();
+                return listMeteredWifiNetworks();
             case "restrict-background-whitelist":
-                return runListRestrictBackgroundWhitelist();
+                return listRestrictBackgroundWhitelist();
         }
         pw.println("Error: unknown list type '" + type + "'");
         return -1;
@@ -172,7 +182,7 @@
         return -1;
     }
 
-    private int runListRestrictBackgroundWhitelist() throws RemoteException {
+    private int listRestrictBackgroundWhitelist() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final int[] uids = mInterface.getRestrictBackgroundWhitelistedUids();
         pw.print("Restrict background whitelisted UIDs: ");
@@ -238,11 +248,11 @@
         return 0;
     }
 
-    private int listNonMobileMeteredNetworks() throws RemoteException {
+    private int listMeteredWifiNetworks() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final String arg = getNextArg();
         final Boolean filter = arg == null ? null : Boolean.valueOf(arg);
-        for (NetworkPolicy policy : getNonMobilePolicies()) {
+        for (NetworkPolicy policy : getWifiPolicies()) {
             if (filter != null && filter.booleanValue() != policy.metered) {
                 continue;
             }
@@ -253,14 +263,14 @@
         return 0;
     }
 
-    private int getNonMobileMeteredNetwork() throws RemoteException {
+    private int getMeteredWifiNetwork() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final String id = getNextArg();
         if (id == null) {
             pw.println("Error: didn't specify ID");
             return -1;
         }
-        final List<NetworkPolicy> policies = getNonMobilePolicies();
+        final List<NetworkPolicy> policies = getWifiPolicies();
         for (NetworkPolicy policy: policies) {
             if (id.equals(getNetworkId(policy))) {
                 pw.println(policy.metered);
@@ -270,7 +280,7 @@
         return 0;
     }
 
-    private int setNonMobileMeteredNetwork() throws RemoteException {
+    private int setMeteredWifiNetwork() throws RemoteException {
         final PrintWriter pw = getOutPrintWriter();
         final String id = getNextArg();
         if (id == null) {
@@ -285,6 +295,7 @@
         final boolean metered = Boolean.valueOf(arg);
         final NetworkPolicy[] policies = mInterface.getNetworkPolicies(null);
         boolean changed = false;
+        // First try to find a policy with such id
         for (NetworkPolicy policy : policies) {
             if (policy.template.isMatchRuleMobile() || policy.metered == metered) {
                 continue;
@@ -298,24 +309,57 @@
         }
         if (changed) {
             mInterface.setNetworkPolicies(policies);
+            return 0;
+        }
+        // Policy not found: check if there is a saved wi-fi with such id.
+        for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
+            final String ssid = removeDoubleQuotes(config.SSID);
+            if (id.equals(ssid)) {
+                final NetworkPolicy policy = newPolicy(ssid);
+                Log.i(TAG, "Creating new policy for " + ssid + ": " + policy);
+                final NetworkPolicy[] newPolicies = new NetworkPolicy[policies.length + 1];
+                System.arraycopy(policies, 0, newPolicies, 0, policies.length);
+                newPolicies[newPolicies.length - 1] = policy;
+                mInterface.setNetworkPolicies(newPolicies);
+            }
         }
         return 0;
     }
 
-    private List<NetworkPolicy> getNonMobilePolicies() throws RemoteException {
+    private List<NetworkPolicy> getWifiPolicies() throws RemoteException {
+        // First gets a list of saved wi-fi networks.
+        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        final Set<String> ssids = new HashSet<>(configs.size());
+        for (WifiConfiguration config : configs) {
+            ssids.add(removeDoubleQuotes(config.SSID));
+        }
+
+        // Then gets the saved policies.
         final NetworkPolicy[] policies = mInterface.getNetworkPolicies(null);
-        final List<NetworkPolicy> nonMobilePolicies = new ArrayList<NetworkPolicy>(policies.length);
+        final List<NetworkPolicy> wifiPolicies = new ArrayList<NetworkPolicy>(policies.length);
         for (NetworkPolicy policy: policies) {
             if (!policy.template.isMatchRuleMobile()) {
-                nonMobilePolicies.add(policy);
+                wifiPolicies.add(policy);
+                final String netId = getNetworkId(policy);
+                ssids.remove(netId);
             }
         }
-        return nonMobilePolicies;
+        // Finally, creates new default policies for saved WI-FIs not policied yet.
+        for (String ssid : ssids) {
+            final NetworkPolicy policy = newPolicy(ssid);
+            wifiPolicies.add(policy);
+        }
+        return wifiPolicies;
+    }
+
+    private NetworkPolicy newPolicy(String ssid) {
+        final NetworkTemplate template = NetworkTemplate.buildTemplateWifi(ssid);
+        final NetworkPolicy policy = newWifiPolicy(template, false);
+        return policy;
     }
 
     private String getNetworkId(NetworkPolicy policy) {
-        // ids are typically enclosed on double quotes (")
-        return policy.template.getNetworkId().replaceAll("^\"|\"$", "");
+        return removeDoubleQuotes(policy.template.getNetworkId());
     }
 
     private int getNextBooleanArg() {
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index ce18818..9820a12 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -234,9 +234,13 @@
                 final ConditionRecord r = getRecordLocked(c.id, info.component, true /*create*/);
                 r.info = info;
                 r.condition = c;
-                if (mCallback != null) {
-                    mCallback.onConditionChanged(c.id, c);
-                }
+            }
+        }
+        final int N = conditions.length;
+        for (int i = 0; i < N; i++) {
+            final Condition c = conditions[i];
+            if (mCallback != null) {
+                mCallback.onConditionChanged(c.id, c);
             }
         }
     }
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 29d52c1..0d6e3e5 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -53,6 +53,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Objects;
@@ -547,14 +548,14 @@
                     loadComponentNamesFromSetting(mConfig.secureSettingName, userIds[i]));
         }
 
-        final ArrayList<ManagedServiceInfo> toRemove = new ArrayList<>();
-        final SparseArray<ArrayList<ComponentName>> toAdd = new SparseArray<>();
+        final ArrayList<ManagedServiceInfo> removableBoundServices = new ArrayList<>();
+        final SparseArray<Set<ComponentName>> toAdd = new SparseArray<>();
 
         synchronized (mMutex) {
-            // Unbind automatically bound services, retain system services.
+            // Potentially unbind automatically bound services, retain system services.
             for (ManagedServiceInfo service : mServices) {
                 if (!service.isSystem && !service.isGuest(this)) {
-                    toRemove.add(service);
+                    removableBoundServices.add(service);
                 }
             }
 
@@ -565,11 +566,11 @@
                 // decode the list of components
                 final ArraySet<ComponentName> userComponents = componentsByUser.get(userIds[i]);
                 if (null == userComponents) {
-                    toAdd.put(userIds[i], new ArrayList<ComponentName>());
+                    toAdd.put(userIds[i], new HashSet<ComponentName>());
                     continue;
                 }
 
-                final ArrayList<ComponentName> add = new ArrayList<>(userComponents);
+                final Set<ComponentName> add = new HashSet<>(userComponents);
 
                 // Remove components from disabled categories so that those services aren't run.
                 for (Entry<String, Boolean> e : mCategoryEnabled.entrySet()) {
@@ -594,19 +595,26 @@
             mEnabledServicesPackageNames = newPackages;
         }
 
-        for (ManagedServiceInfo info : toRemove) {
+        for (ManagedServiceInfo info : removableBoundServices) {
             final ComponentName component = info.component;
             final int oldUser = info.userid;
-            Slog.v(TAG, "disabling " + getCaption() + " for user "
-                    + oldUser + ": " + component);
-            unregisterService(component, info.userid);
+            final Set<ComponentName> allowedComponents = toAdd.get(info.userid);
+            if (allowedComponents != null) {
+                if (allowedComponents.contains(component)) {
+                    // Already bound, don't need to bind again.
+                    allowedComponents.remove(component);
+                } else {
+                    // No longer allowed to be bound.
+                    Slog.v(TAG, "disabling " + getCaption() + " for user "
+                            + oldUser + ": " + component);
+                    unregisterService(component, oldUser);
+                }
+            }
         }
 
         for (int i = 0; i < nUserIds; ++i) {
-            final ArrayList<ComponentName> add = toAdd.get(userIds[i]);
-            final int N = add.size();
-            for (int j = 0; j < N; j++) {
-                final ComponentName component = add.get(j);
+            final Set<ComponentName> add = toAdd.get(userIds[i]);
+            for (ComponentName component : add) {
                 Slog.v(TAG, "enabling " + getCaption() + " for user " + userIds[i] + ": "
                         + component);
                 registerService(component, userIds[i]);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bf8e8fb..ede1a2f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.notification;
 
-import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
 import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationAssistantService.REASON_APP_CANCEL_ALL;
 import static android.service.notification.NotificationAssistantService.REASON_DELEGATE_CANCEL;
@@ -39,6 +38,7 @@
 import static android.service.notification.NotificationListenerService.TRIM_FULL;
 import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
 import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
+import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_NONE;
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.END_TAG;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -460,7 +460,7 @@
     /** Use this to check if a package can post a notification or toast. */
     private boolean checkNotificationOp(String pkg, int uid) {
         return mAppOps.checkOp(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
-                == AppOpsManager.MODE_ALLOWED && !isApplicationSuspended(pkg, uid);
+                == AppOpsManager.MODE_ALLOWED && !isPackageSuspendedForUser(pkg, uid);
     }
 
     private static final class ToastRecord
@@ -1133,14 +1133,14 @@
             }
 
             final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
-            final boolean isApplicationSuspended =
-                    isApplicationSuspended(pkg, Binder.getCallingUid());
+            final boolean isPackageSuspended =
+                    isPackageSuspendedForUser(pkg, Binder.getCallingUid());
 
             if (ENABLE_BLOCKED_TOASTS && (!noteNotificationOp(pkg, Binder.getCallingUid())
-                    || isApplicationSuspended)) {
+                    || isPackageSuspended)) {
                 if (!isSystemToast) {
                     Slog.e(TAG, "Suppressing toast from package " + pkg
-                            + (isApplicationSuspended
+                            + (isPackageSuspended
                                     ? " due to package suspended by administrator."
                                     : " by user request."));
                     return;
@@ -1264,10 +1264,18 @@
          * Use this when you just want to know if notifications are OK for this package.
          */
         @Override
+        public boolean areNotificationsEnabled(String pkg) {
+            return areNotificationsEnabledForPackage(pkg, Binder.getCallingUid());
+        }
+
+        /**
+         * Use this when you just want to know if notifications are OK for this package.
+         */
+        @Override
         public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
-            checkCallerIsSystem();
+            checkCallerIsSystemOrSameApp(pkg);
             return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
-                    == AppOpsManager.MODE_ALLOWED) && !isApplicationSuspended(pkg, uid);
+                    == AppOpsManager.MODE_ALLOWED) && !isPackageSuspendedForUser(pkg, uid);
         }
 
         @Override
@@ -1329,15 +1337,21 @@
         }
 
         @Override
+        public int getTopicImportance(String pkg, String topicId) {
+            checkCallerIsSystemOrSameApp(pkg);
+            return mRankingHelper.getImportance(pkg, Binder.getCallingUid(), topicId);
+        }
+
+        @Override
         public int getImportance(String pkg, int uid, Notification.Topic topic) {
             checkCallerIsSystem();
             return mRankingHelper.getImportance(pkg, uid, topic);
         }
 
         @Override
-        public boolean doesAppUseTopics(String pkg, int uid) {
+        public boolean doesUserUseTopics(String pkg, int uid) {
             enforceSystemOrSystemUI("Caller not system or systemui");
-            return mRankingHelper.doesAppUseTopics(pkg, uid);
+            return mRankingHelper.doesUserUseTopics(pkg, uid);
         }
 
         /**
@@ -2001,6 +2015,9 @@
         @Override
         public void setImportanceFromAssistant(INotificationListener token, String key,
                 int importance, CharSequence explanation) throws RemoteException {
+            if (importance == IMPORTANCE_NONE) {
+                throw new IllegalArgumentException("blocking not allowed: key=" + key);
+            }
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationList) {
@@ -2366,13 +2383,13 @@
 
                 // why is this here?
                 savePolicyFile();
-                final boolean isApplicationSuspended = isApplicationSuspended(pkg, callingUid);
+                final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
 
                 // blocked apps/topics
                 if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
-                        || !noteNotificationOp(pkg, callingUid) || isApplicationSuspended) {
+                        || !noteNotificationOp(pkg, callingUid) || isPackageSuspended) {
                     if (!isSystemNotification) {
-                        if (isApplicationSuspended) {
+                        if (isPackageSuspended) {
                             Slog.e(TAG, "Suppressing notification from package due to package "
                                     + "suspended by administrator.");
                             mUsageStats.registerSuspendedByAdmin(r);
@@ -3474,22 +3491,13 @@
         return true;
     }
 
-    private boolean isApplicationSuspended(String pkg, int uid) {
+    private boolean isPackageSuspendedForUser(String pkg, int uid) {
         int userId = UserHandle.getUserId(uid);
-        ApplicationInfo ai;
         try {
-            // TODO: it might be faster to return a boolean from package manager rather than the
-            // whole application info. Revisit and make the API change.
-            ai = AppGlobals.getPackageManager().getApplicationInfo(pkg, 0, userId);
-            if (ai == null) {
-                Slog.w(TAG, "No application info for package " + pkg + " and user " + userId);
-                return false;
-            }
+            return AppGlobals.getPackageManager().isPackageSuspendedForUser(pkg, userId);
         } catch (RemoteException re) {
             throw new SecurityException("Could not talk to package manager service");
         }
-
-        return ((ai.flags & FLAG_SUSPENDED) != 0);
     }
 
     private class TrimCache {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 484b0e9..12c70a3 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -23,11 +23,13 @@
 
 import android.app.Notification;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
+import android.os.Build;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
@@ -146,6 +148,22 @@
             importance = IMPORTANCE_DEFAULT;
         }
 
+        try {
+            final ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(
+                    sbn.getPackageName(), 0);
+            if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.N) {
+                if (isNoisy) {
+                    if (importance >= IMPORTANCE_HIGH) {
+                        importance = IMPORTANCE_MAX;
+                    } else {
+                        importance = IMPORTANCE_HIGH;
+                    }
+                }
+            }
+        } catch (NameNotFoundException e) {
+            // oh well.
+        }
+
         if (n.fullScreenIntent != null) {
             importance = IMPORTANCE_MAX;
         }
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 1a7e355..9773474 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -36,7 +36,9 @@
 
     int getImportance(String packageName, int uid, Notification.Topic topic);
 
-    boolean doesAppUseTopics(String packageName, int uid);
+    boolean doesUserUseTopics(String packageName, int uid);
 
     boolean hasBannedTopics(String packageName, int uid);
+
+    int getImportance(String packageName, int uid, String topicId);
 }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index aa36e29..91eab10 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -20,6 +20,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.UserHandle;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationListenerService.Ranking;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -467,6 +468,24 @@
     }
 
     /**
+     * Gets the importance of a topic. Unlike {@link #getImportance(String, int, String)}, does not
+     * create package or topic records if they don't exist.
+     */
+    @Override
+    public int getImportance(String packageName, int uid, String topicId) {
+        final String key = recordKey(packageName, uid);
+        Record r = mRecords.get(key);
+        if (r == null) {
+            return Ranking.IMPORTANCE_UNSPECIFIED;
+        }
+        Topic t = r.topics.get(topicId);
+        if (t == null) {
+            return Ranking.IMPORTANCE_UNSPECIFIED;
+        }
+        return t.importance;
+    }
+
+    /**
      * Gets importance. If a topic is given, returns the importance of that topic. Otherwise, the
      * importance of the app.
      */
@@ -502,15 +521,14 @@
     }
 
     @Override
-    public boolean doesAppUseTopics(String pkgName, int uid) {
+    public boolean doesUserUseTopics(String pkgName, int uid) {
         final Record r = getOrCreateRecord(pkgName, uid);
-        int numTopics = r.topics.size();
-        if (numTopics == 0
-                || (numTopics == 1 && r.topics.containsKey(Notification.TOPIC_DEFAULT))) {
-            return false;
-        } else {
-            return true;
+        for (Topic topic : r.topics.values()) {
+            if (topic.importance != Ranking.IMPORTANCE_UNSPECIFIED
+                    && r.importance != topic.importance)
+                return true;
         }
+        return false;
     }
 
     private Topic getOrCreateTopic(Record r, Notification.Topic topic) {
diff --git a/services/core/java/com/android/server/notification/ScheduleCalendar.java b/services/core/java/com/android/server/notification/ScheduleCalendar.java
index cea611d..4c57c1d 100644
--- a/services/core/java/com/android/server/notification/ScheduleCalendar.java
+++ b/services/core/java/com/android/server/notification/ScheduleCalendar.java
@@ -40,16 +40,12 @@
         updateDays();
     }
 
-    public long nextScheduleStart(long time) {
-        if (mSchedule == null || mDays.size() == 0) return Long.MAX_VALUE;
-        final long start = getTime(time, mSchedule.startHour, mSchedule.startMinute);
-        for (int i = 0; i < Calendar.SATURDAY; i++) {
-            final long t = addDays(start, i);
-            if (t > time && isInSchedule(t)) {
-                return t;
+    public void maybeSetNextAlarm(long now, long nextAlarm) {
+        if (mSchedule != null) {
+            if (mSchedule.exitAtAlarm && now > mSchedule.nextAlarm) {
+                mSchedule.nextAlarm = nextAlarm;
             }
         }
-        return Long.MAX_VALUE;
     }
 
     public void setTimeZone(TimeZone tz) {
@@ -60,7 +56,13 @@
         if (mSchedule == null) return 0;
         final long nextStart = getNextTime(now, mSchedule.startHour, mSchedule.startMinute);
         final long nextEnd = getNextTime(now, mSchedule.endHour, mSchedule.endMinute);
-        return Math.min(nextStart, nextEnd);
+        long nextScheduleTime = Math.min(nextStart, nextEnd);
+
+        if (mSchedule.exitAtAlarm && mSchedule.nextAlarm > now) {
+            return Math.min(nextScheduleTime, mSchedule.nextAlarm);
+        } else {
+            return nextScheduleTime;
+        }
     }
 
     private long getNextTime(long now, int hr, int min) {
@@ -84,7 +86,15 @@
         if (end <= start) {
             end = addDays(end, 1);
         }
-        return isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end);
+        boolean isInSchedule =
+                isInSchedule(-1, time, start, end) || isInSchedule(0, time, start, end);
+        if (isInSchedule && mSchedule.exitAtAlarm
+                && mSchedule.nextAlarm != 0
+                && time >= mSchedule.nextAlarm) {
+            return false;
+        } else {
+            return isInSchedule;
+        }
     }
 
     private boolean isInSchedule(int daysOffset, long time, long start, long end) {
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index c9b0ebb..8d0ad96 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -28,7 +29,7 @@
 import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ScheduleInfo;
-import android.util.ArraySet;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 
@@ -42,7 +43,7 @@
  */
 public class ScheduleConditionProvider extends SystemConditionProviderService {
     private static final String TAG = "ConditionProviders.SCP";
-    private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
+    private static final boolean DEBUG = true || Log.isLoggable("ConditionProviders", Log.DEBUG);
 
     public static final ComponentName COMPONENT =
             new ComponentName("android", ScheduleConditionProvider.class.getName());
@@ -53,8 +54,9 @@
     private static final String EXTRA_TIME = "time";
 
     private final Context mContext = this;
-    private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>();
+    private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>();
 
+    private AlarmManager mAlarmManager;
     private boolean mConnected;
     private boolean mRegistered;
     private long mNextAlarmTime;
@@ -80,9 +82,9 @@
         pw.print("      mRegistered="); pw.println(mRegistered);
         pw.println("      mSubscriptions=");
         final long now = System.currentTimeMillis();
-        for (Uri conditionId : mSubscriptions) {
+        for (Uri conditionId : mSubscriptions.keySet()) {
             pw.print("        ");
-            pw.print(meetsSchedule(conditionId, now) ? "* " : "  ");
+            pw.print(meetsSchedule(mSubscriptions.get(conditionId), now) ? "* " : "  ");
             pw.println(conditionId);
         }
         dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now);
@@ -113,7 +115,7 @@
             notifyCondition(conditionId, Condition.STATE_FALSE, "badCondition");
             return;
         }
-        mSubscriptions.add(conditionId);
+        mSubscriptions.put(conditionId, toScheduleCalendar(conditionId));
         evaluateSubscriptions();
     }
 
@@ -135,13 +137,18 @@
     }
 
     private void evaluateSubscriptions() {
+        if (mAlarmManager == null) {
+            mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        }
         setRegistered(!mSubscriptions.isEmpty());
         final long now = System.currentTimeMillis();
         mNextAlarmTime = 0;
-        for (Uri conditionId : mSubscriptions) {
-            final ScheduleCalendar cal = toScheduleCalendar(conditionId);
+        long nextUserAlarmTime = getNextAlarm();
+        for (Uri conditionId : mSubscriptions.keySet()) {
+            final ScheduleCalendar cal = mSubscriptions.get(conditionId);
             if (cal != null && cal.isInSchedule(now)) {
                 notifyCondition(conditionId, Condition.STATE_TRUE, "meetsSchedule");
+                cal.maybeSetNextAlarm(now, nextUserAlarmTime);
             } else {
                 notifyCondition(conditionId, Condition.STATE_FALSE, "!meetsSchedule");
             }
@@ -175,8 +182,13 @@
         }
     }
 
-    private static boolean meetsSchedule(Uri conditionId, long time) {
-        final ScheduleCalendar cal = toScheduleCalendar(conditionId);
+    public long getNextAlarm() {
+        final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(
+                ActivityManager.getCurrentUser());
+        return info != null ? info.getTriggerTime() : 0;
+    }
+
+    private static boolean meetsSchedule(ScheduleCalendar cal, long time) {
         return cal != null && cal.isInSchedule(time);
     }
 
@@ -198,6 +210,7 @@
             filter.addAction(Intent.ACTION_TIME_CHANGED);
             filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
             filter.addAction(ACTION_EVALUATE);
+            filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
             registerReceiver(mReceiver, filter);
         } else {
             unregisterReceiver(mReceiver);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index bba0d40..383c1ab 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -578,7 +578,8 @@
                     ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
                     if (RULE_INSTANCE_GRACE_PERIOD < (currentTime - rule.creationTime)) {
                         try {
-                            mPm.getPackageInfo(rule.component.getPackageName(), 0);
+                            mPm.getPackageInfo(rule.component.getPackageName(),
+                                    PackageManager.MATCH_UNINSTALLED_PACKAGES);
                         } catch (PackageManager.NameNotFoundException e) {
                             newConfig.automaticRules.removeAt(i);
                         }
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 6c338c1..63c9408 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -262,6 +262,7 @@
                 grantRuntimePermissionsLPw(setupPackage, PHONE_PERMISSIONS, userId);
                 grantRuntimePermissionsLPw(setupPackage, CONTACTS_PERMISSIONS, userId);
                 grantRuntimePermissionsLPw(setupPackage, LOCATION_PERMISSIONS, userId);
+                grantRuntimePermissionsLPw(setupPackage, CAMERA_PERMISSIONS, userId);
             }
 
             // Camera
@@ -576,7 +577,7 @@
             }
 
             // Android Wear Home
-            if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) {
                 Intent homeIntent = new Intent(Intent.ACTION_MAIN);
                 homeIntent.addCategory(Intent.CATEGORY_HOME_MAIN);
 
@@ -611,7 +612,7 @@
             PackageParser.Package dialerPackage, int userId) {
         if (doesPackageSupportRuntimePermissions(dialerPackage)) {
             boolean isPhonePermFixed =
-                    mService.hasSystemFeature(PackageManager.FEATURE_WATCH);
+                    mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0);
             grantRuntimePermissionsLPw(
                     dialerPackage, PHONE_PERMISSIONS, isPhonePermFixed, userId);
             grantRuntimePermissionsLPw(dialerPackage, CONTACTS_PERMISSIONS, userId);
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index d82bb3d..8d75f60 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -201,8 +201,7 @@
             long ident = Binder.clearCallingIdentity();
             try {
                 List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                        user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 return new ParceledListSlice<>(apps);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -220,7 +219,7 @@
             long ident = Binder.clearCallingIdentity();
             try {
                 ResolveInfo app = mPm.resolveActivityAsUser(intent,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 return app;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -239,7 +238,7 @@
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 PackageInfo info = pm.getPackageInfo(packageName,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 return info != null && info.applicationInfo.enabled;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -277,7 +276,7 @@
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 ActivityInfo info = pm.getActivityInfo(component,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 return info != null;
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -303,7 +302,7 @@
             try {
                 IPackageManager pm = AppGlobals.getPackageManager();
                 ActivityInfo info = pm.getActivityInfo(component,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 if (!info.exported) {
                     throw new SecurityException("Cannot launch non-exported components "
                             + component);
@@ -313,7 +312,7 @@
                 // as calling startActivityAsUser ignores the category and just
                 // resolves based on the component if present.
                 List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, user.getIdentifier());
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, user.getIdentifier());
                 final int size = apps.size();
                 for (int i = 0; i < size; ++i) {
                     ActivityInfo activityInfo = apps.get(i).activityInfo;
@@ -347,8 +346,7 @@
                 String packageName = component.getPackageName();
                 Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                         Uri.fromParts("package", packageName, null));
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |
-                        Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                 intent.setSourceBounds(sourceBounds);
                 mContext.startActivityAsUser(intent, opts, user);
             } finally {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index da62a2d..94b3b2d 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -55,8 +55,6 @@
 public class OtaDexoptService extends IOtaDexopt.Stub {
     private final static String TAG = "OTADexopt";
     private final static boolean DEBUG_DEXOPT = true;
-    // Apps used in the last 7 days.
-    private final static long DEXOPT_LRU_THRESHOLD_IN_MINUTES = 7 * 24 * 60;
 
     private final Context mContext;
     private final PackageDexOptimizer mPackageDexOptimizer;
@@ -94,69 +92,9 @@
         if (mDexoptPackages != null) {
             throw new IllegalStateException("already called prepare()");
         }
-
-        mDexoptPackages = new LinkedList<>();
-
-        ArrayList<PackageParser.Package> pkgs;
         synchronized (mPackageManagerService.mPackages) {
-            pkgs = new ArrayList<PackageParser.Package>(mPackageManagerService.mPackages.values());
-        }
-
-        // Sort apps by importance for dexopt ordering. Important apps are given more priority
-        // in case the device runs out of space.
-
-        // Give priority to core apps.
-        for (PackageParser.Package pkg : pkgs) {
-            if (pkg.coreApp) {
-                if (DEBUG_DEXOPT) {
-                    Log.i(TAG, "Adding core app " + mDexoptPackages.size() + ": " + pkg.packageName);
-                }
-                mDexoptPackages.add(pkg);
-            }
-        }
-        pkgs.removeAll(mDexoptPackages);
-
-        // 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 (PackageParser.Package pkg : pkgs) {
-            if (pkgNames.contains(pkg.packageName)) {
-                if (DEBUG_DEXOPT) {
-                    Log.i(TAG, "Adding pre boot system app " + mDexoptPackages.size() + ": " +
-                            pkg.packageName);
-                }
-                mDexoptPackages.add(pkg);
-            }
-        }
-        pkgs.removeAll(mDexoptPackages);
-
-        // Filter out packages that aren't recently used, add all remaining apps.
-        // TODO: add a property to control this?
-        if (mPackageManagerService.isHistoricalPackageUsageAvailable()) {
-            filterRecentlyUsedApps(pkgs, DEXOPT_LRU_THRESHOLD_IN_MINUTES * 60 * 1000);
-        }
-        mDexoptPackages.addAll(pkgs);
-
-        // Now go ahead and also add the libraries required for these packages.
-        // TODO: Think about interleaving things.
-        Set<PackageParser.Package> dependencies = new HashSet<>();
-        for (PackageParser.Package p : mDexoptPackages) {
-            dependencies.addAll(mPackageManagerService.findSharedNonSystemLibraries(p));
-        }
-        if (!dependencies.isEmpty()) {
-            dependencies.removeAll(mDexoptPackages);
-        }
-        mDexoptPackages.addAll(dependencies);
-
-        if (DEBUG_DEXOPT) {
-            StringBuilder sb = new StringBuilder();
-            for (PackageParser.Package pkg : mDexoptPackages) {
-                if (sb.length() > 0) {
-                    sb.append(", ");
-                }
-                sb.append(pkg.packageName);
-            }
-            Log.i(TAG, "Packages to be optimized: " + sb.toString());
+            mDexoptPackages = PackageManagerServiceUtils.getPackagesForDexopt(
+                    mPackageManagerService.mPackages.values(), mPackageManagerService);
         }
     }
 
@@ -228,29 +166,6 @@
         return pkgNames;
     }
 
-    private void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs,
-            long dexOptLRUThresholdInMills) {
-        // Filter out packages that aren't recently used.
-        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 + dexOptLRUThresholdInMills < 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 static class OTADexoptPackageDexOptimizer extends
             PackageDexOptimizer.ForcedUpdatePackageDexOptimizer {
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 23a58d0..928c19f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -212,8 +212,8 @@
         mCallbacks = new Callbacks(mInstallThread.getLooper());
 
         mSessionsFile = new AtomicFile(
-                new File(Environment.getSystemSecureDirectory(), "install_sessions.xml"));
-        mSessionsDir = new File(Environment.getSystemSecureDirectory(), "install_sessions");
+                new File(Environment.getDataSystemDirectory(), "install_sessions.xml"));
+        mSessionsDir = new File(Environment.getDataSystemDirectory(), "install_sessions");
         mSessionsDir.mkdirs();
 
         synchronized (mSessions) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ada7458..cc5b80e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -24,6 +24,7 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
@@ -64,12 +65,14 @@
 import static android.content.pm.PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
+import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
 import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
 import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
 import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
 import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
 import static android.content.pm.PackageParser.isApkFile;
 import static android.os.Process.PACKAGE_INFO_GID;
 import static android.os.Process.SYSTEM_UID;
@@ -97,7 +100,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
-import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
@@ -139,7 +141,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.ActivityIntentInfo;
-import android.content.pm.PackageParser.Package;
 import android.content.pm.PackageParser.PackageLite;
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.PackageStats;
@@ -263,7 +264,6 @@
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
@@ -357,6 +357,7 @@
     static final int SCAN_REQUIRE_KNOWN = 1<<12;
     static final int SCAN_MOVE = 1<<13;
     static final int SCAN_INITIAL = 1<<14;
+    static final int SCAN_CHECK_ONLY = 1<<15;
 
     static final int REMOVE_CHATTY = 1<<16;
 
@@ -1418,159 +1419,33 @@
 
                     PostInstallData data = mRunningInstalls.get(msg.arg1);
                     mRunningInstalls.delete(msg.arg1);
-                    boolean deleteOld = false;
 
                     if (data != null) {
                         InstallArgs args = data.args;
-                        PackageInstalledInfo res = data.res;
+                        PackageInstalledInfo parentRes = data.res;
 
-                        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                            final String packageName = res.pkg.applicationInfo.packageName;
-                            res.removedInfo.sendBroadcast(false, true, false);
-                            Bundle extras = new Bundle(1);
-                            extras.putInt(Intent.EXTRA_UID, res.uid);
+                        final boolean grantPermissions = (args.installFlags
+                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
+                        final String[] grantedPermissions = args.installGrantPermissions;
 
-                            // Now that we successfully installed the package, grant runtime
-                            // permissions if requested before broadcasting the install.
-                            if ((args.installFlags
-                                    & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
-                                    && res.pkg.applicationInfo.targetSdkVersion
-                                            >= Build.VERSION_CODES.M) {
-                                grantRequestedRuntimePermissions(res.pkg, args.user.getIdentifier(),
-                                        args.installGrantPermissions);
-                            }
+                        // Handle the parent package
+                        handlePackagePostInstall(parentRes, grantPermissions, grantedPermissions,
+                                args.observer);
 
-                            synchronized (mPackages) {
-                                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
-                            }
-
-                            // Determine the set of users who are adding this
-                            // package for the first time vs. those who are seeing
-                            // an update.
-                            int[] firstUsers;
-                            int[] updateUsers = new int[0];
-                            if (res.origUsers == null || res.origUsers.length == 0) {
-                                firstUsers = res.newUsers;
-                            } else {
-                                firstUsers = new int[0];
-                                for (int i=0; i<res.newUsers.length; i++) {
-                                    int user = res.newUsers[i];
-                                    boolean isNew = true;
-                                    for (int j=0; j<res.origUsers.length; j++) {
-                                        if (res.origUsers[j] == user) {
-                                            isNew = false;
-                                            break;
-                                        }
-                                    }
-                                    if (isNew) {
-                                        int[] newFirst = new int[firstUsers.length+1];
-                                        System.arraycopy(firstUsers, 0, newFirst, 0,
-                                                firstUsers.length);
-                                        newFirst[firstUsers.length] = user;
-                                        firstUsers = newFirst;
-                                    } else {
-                                        int[] newUpdate = new int[updateUsers.length+1];
-                                        System.arraycopy(updateUsers, 0, newUpdate, 0,
-                                                updateUsers.length);
-                                        newUpdate[updateUsers.length] = user;
-                                        updateUsers = newUpdate;
-                                    }
-                                }
-                            }
-                            // don't broadcast for ephemeral installs/updates
-                            final boolean isEphemeral = isEphemeral(res.pkg);
-                            if (!isEphemeral) {
-                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                                        extras, 0 /*flags*/, null /*targetPackage*/,
-                                        null /*finishedReceiver*/, firstUsers);
-                            }
-                            final boolean update = res.removedInfo.removedPackage != null;
-                            if (update) {
-                                extras.putBoolean(Intent.EXTRA_REPLACING, true);
-                            }
-                            if (!isEphemeral) {
-                                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                                        extras, 0 /*flags*/, null /*targetPackage*/,
-                                        null /*finishedReceiver*/, updateUsers);
-                            }
-                            if (update) {
-                                if (!isEphemeral) {
-                                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
-                                            packageName, extras, 0 /*flags*/,
-                                            null /*targetPackage*/, null /*finishedReceiver*/,
-                                            updateUsers);
-                                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
-                                            null /*package*/, null /*extras*/, 0 /*flags*/,
-                                            packageName /*targetPackage*/,
-                                            null /*finishedReceiver*/, updateUsers);
-                                }
-
-                                // treat asec-hosted packages like removable media on upgrade
-                                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
-                                    if (DEBUG_INSTALL) {
-                                        Slog.i(TAG, "upgrading pkg " + res.pkg
-                                                + " is ASEC-hosted -> AVAILABLE");
-                                    }
-                                    int[] uidArray = new int[] { res.pkg.applicationInfo.uid };
-                                    ArrayList<String> pkgList = new ArrayList<String>(1);
-                                    pkgList.add(packageName);
-                                    sendResourcesChangedBroadcast(true, true,
-                                            pkgList,uidArray, null);
-                                }
-                            }
-                            if (res.removedInfo.args != null) {
-                                // Remove the replaced package's older resources safely now
-                                deleteOld = true;
-                            }
-
-
-                            // Work that needs to happen on first install within each user
-                            if (firstUsers.length > 0) {
-                                for (int userId : firstUsers) {
-                                    synchronized (mPackages) {
-                                        // If this app is a browser and it's newly-installed for
-                                        // some users, clear any default-browser state in those
-                                        // users.  The app's nature doesn't depend on the user,
-                                        // so we can just check its browser nature in any user
-                                        // and generalize.
-                                        if (packageIsBrowser(packageName, firstUsers[0])) {
-                                            mSettings.setDefaultBrowserPackageNameLPw(
-                                                    null, userId);
-                                        }
-
-                                        // We may also need to apply pending (restored) runtime
-                                        // permission grants within these users.
-                                        mSettings.applyPendingPermissionGrantsLPw(
-                                                packageName, userId);
-                                    }
-                                }
-                            }
-                            // Log current value of "unknown sources" setting
-                            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
-                                getUnknownSourcesSettings());
+                        // Handle the child packages
+                        final int childCount = (parentRes.addedChildPackages != null)
+                                ? parentRes.addedChildPackages.size() : 0;
+                        for (int i = 0; i < childCount; i++) {
+                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
+                            handlePackagePostInstall(childRes, grantPermissions, grantedPermissions,
+                                    args.observer);
                         }
-                        // Force a gc to clear up things
-                        Runtime.getRuntime().gc();
-                        // We delete after a gc for applications  on sdcard.
-                        if (deleteOld) {
-                            synchronized (mInstallLock) {
-                                res.removedInfo.args.doPostDeleteLI(true);
-                            }
-                        }
-                        if (args.observer != null) {
-                            try {
-                                Bundle extras = extrasForInstallResult(res);
-                                args.observer.onPackageInstalled(res.name, res.returnCode,
-                                        res.returnMsg, extras);
-                            } catch (RemoteException e) {
-                                Slog.i(TAG, "Observer no longer exists.");
-                            }
-                        }
+
+                        // Log tracing if needed
                         if (args.traceMethod != null) {
                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
                                     args.traceCookie);
                         }
-                        return;
                     } else {
                         Slog.e(TAG, "Bogus post-install token " + msg.arg1);
                     }
@@ -1757,6 +1632,185 @@
         }
     }
 
+    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
+            String[] grantedPermissions, IPackageInstallObserver2 installObserver) {
+        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
+            // Send the removed broadcasts
+            if (res.removedInfo != null) {
+                res.removedInfo.sendPackageRemovedBroadcasts();
+            }
+
+            // Now that we successfully installed the package, grant runtime
+            // permissions if requested before broadcasting the install.
+            if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion
+                    >= Build.VERSION_CODES.M) {
+                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
+            }
+
+            final boolean update = res.removedInfo != null
+                    && res.removedInfo.removedPackage != null;
+
+            // If this is the first time we have child packages for a disabled privileged
+            // app that had no children, we grant requested runtime permissions to the new
+            // children if the parent on the system image had them already granted.
+            if (res.pkg.parentPackage != null) {
+                synchronized (mPackages) {
+                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
+                }
+            }
+
+            synchronized (mPackages) {
+                mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg);
+            }
+
+            final String packageName = res.pkg.applicationInfo.packageName;
+            Bundle extras = new Bundle(1);
+            extras.putInt(Intent.EXTRA_UID, res.uid);
+
+            // Determine the set of users who are adding this package for
+            // the first time vs. those who are seeing an update.
+            int[] firstUsers = EMPTY_INT_ARRAY;
+            int[] updateUsers = EMPTY_INT_ARRAY;
+            if (res.origUsers == null || res.origUsers.length == 0) {
+                firstUsers = res.newUsers;
+            } else {
+                for (int newUser : res.newUsers) {
+                    boolean isNew = true;
+                    for (int origUser : res.origUsers) {
+                        if (origUser == newUser) {
+                            isNew = false;
+                            break;
+                        }
+                    }
+                    if (isNew) {
+                        firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
+                    } else {
+                        updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
+                    }
+                }
+            }
+
+            // Send installed broadcasts if the install/update is not ephemeral
+            if (!isEphemeral(res.pkg)) {
+                // Send added for users that see the package for the first time
+                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+                        extras, 0 /*flags*/, null /*targetPackage*/,
+                        null /*finishedReceiver*/, firstUsers);
+
+                // Send added for users that don't see the package for the first time
+                if (update) {
+                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
+                }
+                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+                        extras, 0 /*flags*/, null /*targetPackage*/,
+                        null /*finishedReceiver*/, updateUsers);
+
+                // Send replaced for users that don't see the package for the first time
+                if (update) {
+                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
+                            packageName, extras, 0 /*flags*/,
+                            null /*targetPackage*/, null /*finishedReceiver*/,
+                            updateUsers);
+                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
+                            null /*package*/, null /*extras*/, 0 /*flags*/,
+                            packageName /*targetPackage*/,
+                            null /*finishedReceiver*/, updateUsers);
+                }
+
+                // Send broadcast package appeared if forward locked/external for all users
+                // treat asec-hosted packages like removable media on upgrade
+                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
+                    if (DEBUG_INSTALL) {
+                        Slog.i(TAG, "upgrading pkg " + res.pkg
+                                + " is ASEC-hosted -> AVAILABLE");
+                    }
+                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
+                    ArrayList<String> pkgList = new ArrayList<>(1);
+                    pkgList.add(packageName);
+                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
+                }
+            }
+
+            // Work that needs to happen on first install within each user
+            if (firstUsers != null && firstUsers.length > 0) {
+                synchronized (mPackages) {
+                    for (int userId : firstUsers) {
+                        // If this app is a browser and it's newly-installed for some
+                        // users, clear any default-browser state in those users. The
+                        // app's nature doesn't depend on the user, so we can just check
+                        // its browser nature in any user and generalize.
+                        if (packageIsBrowser(packageName, userId)) {
+                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
+                        }
+
+                        // We may also need to apply pending (restored) runtime
+                        // permission grants within these users.
+                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
+                    }
+                }
+            }
+
+            // Log current value of "unknown sources" setting
+            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
+                    getUnknownSourcesSettings());
+
+            // Force a gc to clear up things
+            Runtime.getRuntime().gc();
+
+            // Remove the replaced package's older resources safely now
+            // We delete after a gc for applications  on sdcard.
+            if (res.removedInfo != null && res.removedInfo.args != null) {
+                synchronized (mInstallLock) {
+                    res.removedInfo.args.doPostDeleteLI(true);
+                }
+            }
+        }
+
+        // If someone is watching installs - notify them
+        if (installObserver != null) {
+            try {
+                Bundle extras = extrasForInstallResult(res);
+                installObserver.onPackageInstalled(res.name, res.returnCode,
+                        res.returnMsg, extras);
+            } catch (RemoteException e) {
+                Slog.i(TAG, "Observer no longer exists.");
+            }
+        }
+    }
+
+    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
+            PackageParser.Package pkg) {
+        if (pkg.parentPackage == null) {
+            return;
+        }
+        if (pkg.requestedPermissions == null) {
+            return;
+        }
+        final PackageSetting disabledSysParentPs = mSettings
+                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
+        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
+                || !disabledSysParentPs.isPrivileged()
+                || (disabledSysParentPs.childPackageNames != null
+                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
+            return;
+        }
+        final int[] allUserIds = sUserManager.getUserIds();
+        final int permCount = pkg.requestedPermissions.size();
+        for (int i = 0; i < permCount; i++) {
+            String permission = pkg.requestedPermissions.get(i);
+            BasePermission bp = mSettings.mPermissions.get(permission);
+            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
+                continue;
+            }
+            for (int userId : allUserIds) {
+                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
+                        permission, userId)) {
+                    grantRuntimePermission(pkg.packageName, permission, userId);
+                }
+            }
+        }
+    }
+
     private StorageEventListener mStorageListener = new StorageEventListener() {
         @Override
         public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
@@ -1811,18 +1865,10 @@
         }
     };
 
-    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId,
+    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
             String[] grantedPermissions) {
-        if (userId >= UserHandle.USER_SYSTEM) {
+        for (int userId : userIds) {
             grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
-        } else if (userId == UserHandle.USER_ALL) {
-            final int[] userIds;
-            synchronized (mPackages) {
-                userIds = UserManagerService.getInstance().getUserIds();
-            }
-            for (int someUserId : userIds) {
-                grantRequestedRuntimePermissionsForUser(pkg, someUserId, grantedPermissions);
-            }
         }
 
         // We could have touched GID membership, so flush out packages.list
@@ -1886,11 +1932,20 @@
         }
     }
 
+    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
+        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
+        scheduleWritePackageRestrictionsLocked(userId);
+    }
+
     void scheduleWritePackageRestrictionsLocked(int userId) {
-        if (!sUserManager.exists(userId)) return;
-        mDirtyUsers.add(userId);
-        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
-            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
+        final int[] userIds = (userId == UserHandle.USER_ALL)
+                ? sUserManager.getUserIds() : new int[]{userId};
+        for (int nextUserId : userIds) {
+            if (!sUserManager.exists(nextUserId)) return;
+            mDirtyUsers.add(nextUserId);
+            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
+                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
+            }
         }
     }
 
@@ -2216,7 +2271,7 @@
                                     + ps.codePathString + ", installStatus=" + ps.installStatus
                                     + ", versionCode=" + ps.versionCode + "; scanned versionCode="
                                     + scannedPkg.mVersionCode);
-                            removePackageLI(ps, true);
+                            removePackageLI(scannedPkg, true);
                             mExpectingBetter.put(ps.name, ps.codePath);
                         }
 
@@ -2842,6 +2897,10 @@
                 throw new SecurityException("Package " + packageName + " was not found!");
             }
 
+            if (mSafeMode && !ps.isSystem()) {
+                throw new SecurityException("Package " + packageName + " not a system app!");
+            }
+
             if (ps.frozen) {
                 throw new SecurityException("Package " + packageName + " is currently frozen!");
             }
@@ -3221,12 +3280,6 @@
                 flags |= PackageManager.MATCH_ENCRYPTION_AWARE;
             }
         }
-
-        // Safe mode means we should ignore any third-party apps
-        if (mSafeMode) {
-            flags |= PackageManager.MATCH_SYSTEM_ONLY;
-        }
-
         return flags;
     }
 
@@ -3286,6 +3339,12 @@
             Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
                     + " with flags 0x" + Integer.toHexString(flags), new Throwable());
         }
+
+        // Safe mode means we shouldn't match any third-party components
+        if (mSafeMode) {
+            flags |= PackageManager.MATCH_SYSTEM_ONLY;
+        }
+
         return updateFlags(flags, userId);
     }
 
@@ -3414,6 +3473,18 @@
     }
 
     @Override
+    public @Nullable String getServicesSystemSharedLibraryPackageName() {
+        synchronized (mPackages) {
+            SharedLibraryEntry libraryEntry = mSharedLibraries.get(
+                    PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES);
+            if (libraryEntry != null) {
+                return libraryEntry.apk;
+            }
+        }
+        return null;
+    }
+
+    @Override
     public FeatureInfo[] getSystemAvailableFeatures() {
         Collection<FeatureInfo> featSet;
         synchronized (mPackages) {
@@ -3433,9 +3504,14 @@
     }
 
     @Override
-    public boolean hasSystemFeature(String name) {
+    public boolean hasSystemFeature(String name, int version) {
         synchronized (mPackages) {
-            return mAvailableFeatures.containsKey(name);
+            final FeatureInfo feat = mAvailableFeatures.get(name);
+            if (feat == null) {
+                return false;
+            } else {
+                return feat.version >= version;
+            }
         }
     }
 
@@ -4168,7 +4244,8 @@
             } else if (actionName != null) {
                 // TODO: remove these terrible hacks
                 if (actionName.startsWith("android.net.netmon.lingerExpired")
-                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")) {
+                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
+                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")) {
                     return true;
                 }
             }
@@ -6263,9 +6340,8 @@
         }
     }
 
-    private void collectCertificatesLI(PackageParser pp, PackageSetting ps,
-            PackageParser.Package pkg, File srcFile, int parseFlags)
-            throws PackageManagerException {
+    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
+            int parseFlags) throws PackageManagerException {
         if (ps != null
                 && ps.codePath.equals(srcFile)
                 && ps.timeStamp == srcFile.lastModified()
@@ -6294,7 +6370,7 @@
         }
 
         try {
-            pp.collectCertificates(pkg, parseFlags);
+            PackageParser.collectCertificates(pkg, parseFlags);
         } catch (PackageParserException e) {
             throw PackageManagerException.from(e);
         }
@@ -6338,6 +6414,56 @@
             throw PackageManagerException.from(e);
         }
 
+        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
+    }
+
+    /**
+     *  Scans a package and returns the newly parsed package.
+     *  @throws PackageManagerException on a parse error.
+     */
+    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
+            int parseFlags, int scanFlags, long currentTime, UserHandle user)
+            throws PackageManagerException {
+        // If the package has children and this is the first dive in the function
+        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
+        // packages (parent and children) would be successfully scanned before the
+        // actual scan since scanning mutates internal state and we want to atomically
+        // install the package and its children.
+        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
+            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
+                scanFlags |= SCAN_CHECK_ONLY;
+            }
+        } else {
+            scanFlags &= ~SCAN_CHECK_ONLY;
+        }
+
+        // Scan the parent
+        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags,
+                scanFlags, currentTime, user);
+
+        // Scan the children
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPackage = pkg.childPackages.get(i);
+            scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags,
+                    currentTime, user);
+        }
+
+
+        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
+            return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
+        }
+
+        return scannedPkg;
+    }
+
+    /**
+     *  Scans a package and returns the newly parsed package.
+     *  @throws PackageManagerException on a parse error.
+     */
+    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
+            int parseFlags, int scanFlags, long currentTime, UserHandle user)
+            throws PackageManagerException {
         PackageSetting ps = null;
         PackageSetting updatedPkg;
         // reader
@@ -6358,7 +6484,39 @@
             // package name depending on our state.
             updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
             if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
+
+            // If this is a package we don't know about on the system partition, we
+            // may need to remove disabled child packages on the system partition
+            // or may need to not add child packages if the parent apk is updated
+            // on the data partition and no longer defines this child package.
+            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
+                // If this is a parent package for an updated system app and this system
+                // app got an OTA update which no longer defines some of the child packages
+                // we have to prune them from the disabled system packages.
+                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+                if (disabledPs != null) {
+                    final int scannedChildCount = (pkg.childPackages != null)
+                            ? pkg.childPackages.size() : 0;
+                    final int disabledChildCount = disabledPs.childPackageNames != null
+                            ? disabledPs.childPackageNames.size() : 0;
+                    for (int i = 0; i < disabledChildCount; i++) {
+                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
+                        boolean disabledPackageAvailable = false;
+                        for (int j = 0; j < scannedChildCount; j++) {
+                            PackageParser.Package childPkg = pkg.childPackages.get(j);
+                            if (childPkg.packageName.equals(disabledChildPackageName)) {
+                                disabledPackageAvailable = true;
+                                break;
+                            }
+                         }
+                         if (!disabledPackageAvailable) {
+                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
+                         }
+                    }
+                }
+            }
         }
+
         boolean updatedPkgBetter = false;
         // First check if this is a system package that may involve an update
         if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
@@ -6391,10 +6549,24 @@
                         updatedPkg.resourcePathString = scanFile.toString();
                     }
                     updatedPkg.pkg = pkg;
-                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
-                            "Package " + ps.name + " at " + scanFile
-                                    + " ignored: updated version " + ps.versionCode
-                                    + " better than this " + pkg.mVersionCode);
+                    updatedPkg.versionCode = pkg.mVersionCode;
+
+                    // Update the disabled system child packages to point to the package too.
+                    final int childCount = updatedPkg.childPackageNames != null
+                            ? updatedPkg.childPackageNames.size() : 0;
+                    for (int i = 0; i < childCount; i++) {
+                        String childPackageName = updatedPkg.childPackageNames.get(i);
+                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
+                                childPackageName);
+                        if (updatedChildPkg != null) {
+                            updatedChildPkg.pkg = pkg;
+                            updatedChildPkg.versionCode = pkg.mVersionCode;
+                        }
+                    }
+
+                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
+                            + scanFile + " ignored: updated version " + ps.versionCode
+                            + " better than this " + pkg.mVersionCode);
                 } else {
                     // The current app on the system partition is better than
                     // what we have updated to on the data partition; switch
@@ -6439,7 +6611,7 @@
         }
 
         // Verify certificates against what was last scanned
-        collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags);
+        collectCertificatesLI(ps, pkg, scanFile, parseFlags);
 
         /*
          * A new system app appeared, but we already had a non-system one of the
@@ -6456,7 +6628,7 @@
                     != PackageManager.SIGNATURE_MATCH) {
                 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
                         + " signatures don't match existing userdata copy; removing");
-                deletePackageLI(pkg.packageName, null, true, null, null, 0, null, false);
+                deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null);
                 ps = null;
             } else {
                 /*
@@ -6515,13 +6687,13 @@
         }
 
         // Set application objects path explicitly.
-        pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
-        pkg.applicationInfo.setCodePath(pkg.codePath);
-        pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
-        pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
-        pkg.applicationInfo.setResourcePath(resourcePath);
-        pkg.applicationInfo.setBaseResourcePath(baseResourcePath);
-        pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
+        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+        pkg.setApplicationInfoCodePath(pkg.codePath);
+        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+        pkg.setApplicationInfoResourcePath(resourcePath);
+        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
+        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
 
         // Note that we invoke the following method only if we are about to unpack an application
         PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
@@ -6534,7 +6706,7 @@
          */
         if (shouldHideSystemApp) {
             synchronized (mPackages) {
-                mSettings.disableSystemPackageLPw(pkg.packageName);
+                mSettings.disableSystemPackageLPw(pkg.packageName, true);
             }
         }
 
@@ -6658,32 +6830,19 @@
         // Extract pacakges only if profile-guided compilation is enabled because
         // otherwise BackgroundDexOptService will not dexopt them later.
         if (mUseJitProfiles) {
-            ArraySet<String> pkgs = getOptimizablePackages();
-            if (pkgs != null) {
-                for (String pkg : pkgs) {
-                    performDexOpt(pkg, null /* instructionSet */, false /* useProfiles */,
-                            true /* extractOnly */, false /* force */);
+            List<PackageParser.Package> pkgs;
+            synchronized (mPackages) {
+                pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
+            }
+            for (PackageParser.Package pkg : pkgs) {
+                if (PackageDexOptimizer.canOptimizePackage(pkg)) {
+                    performDexOpt(pkg.packageName, null /* instructionSet */,
+                             false /* useProfiles */, true /* extractOnly */, false /* force */);
                 }
             }
         }
     }
 
-    private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
-        List<ResolveInfo> ris = null;
-        try {
-            ris = AppGlobals.getPackageManager().queryIntentReceivers(
-                    intent, null, 0, userId);
-        } catch (RemoteException e) {
-        }
-        ArraySet<String> pkgNames = new ArraySet<String>();
-        if (ris != null) {
-            for (ResolveInfo ri : ris) {
-                pkgNames.add(ri.activityInfo.packageName);
-            }
-        }
-        return pkgNames;
-    }
-
     @Override
     public void notifyPackageUse(String packageName) {
         synchronized (mPackages) {
@@ -6932,17 +7091,62 @@
     }
 
     private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) {
+        final PackageParser.Package pkg;
+        synchronized (mPackages) {
+            pkg = mPackages.get(packageName);
+        }
+        if (pkg == null) {
+            Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName);
+            return;
+        }
+        deleteCodeCacheDirsLI(pkg);
+    }
+
+    private void deleteCodeCacheDirsLI(PackageParser.Package pkg) {
         // TODO: triage flags as part of 26466827
         final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE;
 
-        final int[] users = sUserManager.getUserIds();
+        int[] users = sUserManager.getUserIds();
+        int res = 0;
         for (int user : users) {
+            // Remove the parent code cache
             try {
-                mInstaller.clearAppData(volumeUuid, packageName, user,
+                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user,
                         flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
             } catch (InstallerException e) {
                 Slog.w(TAG, "Failed to delete code cache directory", e);
             }
+            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                PackageParser.Package childPkg = pkg.childPackages.get(i);
+                // Remove the child code cache
+                try {
+                    mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName,
+                            user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+                } catch (InstallerException e) {
+                    Slog.w(TAG, "Failed to delete code cache directory", e);
+                }
+            }
+        }
+    }
+
+    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
+            long lastUpdateTime) {
+        // Set parent install/update time
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps != null) {
+            ps.firstInstallTime = firstInstallTime;
+            ps.lastUpdateTime = lastUpdateTime;
+        }
+        // Set children install/update time
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            ps = (PackageSetting) childPkg.mExtras;
+            if (ps != null) {
+                ps.firstInstallTime = firstInstallTime;
+                ps.lastUpdateTime = lastUpdateTime;
+            }
         }
     }
 
@@ -7066,11 +7270,39 @@
     private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags,
             int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
+        // If the package has children and this is the first dive in the function
+        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
+        // whether all packages (parent and children) would be successfully scanned
+        // before the actual scan since scanning mutates internal state and we want
+        // to atomically install the package and its children.
+        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
+            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
+                scanFlags |= SCAN_CHECK_ONLY;
+            }
+        } else {
+            scanFlags &= ~SCAN_CHECK_ONLY;
+        }
+
+        final PackageParser.Package scannedPkg;
         try {
-            return scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
+            // Scan the parent
+            scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
+            // Scan the children
+            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                PackageParser.Package childPkg = pkg.childPackages.get(i);
+                scanPackageLI(childPkg, parseFlags,
+                        scanFlags, currentTime, user);
+            }
         } finally {
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
+
+        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
+            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
+        }
+
+        return scannedPkg;
     }
 
     private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
@@ -7089,7 +7321,8 @@
     }
 
     private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags,
-            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
+            int scanFlags, long currentTime, UserHandle user)
+            throws PackageManagerException {
         final File scanFile = new File(pkg.codePath);
         if (pkg.applicationInfo.getCodePath() == null ||
                 pkg.applicationInfo.getResourcePath() == null) {
@@ -7125,28 +7358,30 @@
                             "Core android package being redefined.  Skipping.");
                 }
 
-                // Set up information for our fall-back user intent resolution activity.
-                mPlatformPackage = pkg;
-                pkg.mVersionCode = mSdkVersion;
-                mAndroidApplication = pkg.applicationInfo;
+                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
+                    // Set up information for our fall-back user intent resolution activity.
+                    mPlatformPackage = pkg;
+                    pkg.mVersionCode = mSdkVersion;
+                    mAndroidApplication = pkg.applicationInfo;
 
-                if (!mResolverReplaced) {
-                    mResolveActivity.applicationInfo = mAndroidApplication;
-                    mResolveActivity.name = ResolverActivity.class.getName();
-                    mResolveActivity.packageName = mAndroidApplication.packageName;
-                    mResolveActivity.processName = "system:ui";
-                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
-                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
-                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
-                    mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
-                    mResolveActivity.exported = true;
-                    mResolveActivity.enabled = true;
-                    mResolveInfo.activityInfo = mResolveActivity;
-                    mResolveInfo.priority = 0;
-                    mResolveInfo.preferredOrder = 0;
-                    mResolveInfo.match = 0;
-                    mResolveComponentName = new ComponentName(
-                            mAndroidApplication.packageName, mResolveActivity.name);
+                    if (!mResolverReplaced) {
+                        mResolveActivity.applicationInfo = mAndroidApplication;
+                        mResolveActivity.name = ResolverActivity.class.getName();
+                        mResolveActivity.packageName = mAndroidApplication.packageName;
+                        mResolveActivity.processName = "system:ui";
+                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
+                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+                        mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert;
+                        mResolveActivity.exported = true;
+                        mResolveActivity.enabled = true;
+                        mResolveInfo.activityInfo = mResolveActivity;
+                        mResolveInfo.priority = 0;
+                        mResolveInfo.preferredOrder = 0;
+                        mResolveInfo.match = 0;
+                        mResolveComponentName = new ComponentName(
+                                mAndroidApplication.packageName, mResolveActivity.name);
+                    }
                 }
             }
         }
@@ -7156,39 +7391,43 @@
                 Log.d(TAG, "Scanning package " + pkg.packageName);
         }
 
-        if (mPackages.containsKey(pkg.packageName)
-                || mSharedLibraries.containsKey(pkg.packageName)) {
-            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
-                    "Application package " + pkg.packageName
-                    + " already installed.  Skipping duplicate.");
-        }
+        synchronized (mPackages) {
+            if (mPackages.containsKey(pkg.packageName)
+                    || mSharedLibraries.containsKey(pkg.packageName)) {
+                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
+                        "Application package " + pkg.packageName
+                                + " already installed.  Skipping duplicate.");
+            }
 
-        // If we're only installing presumed-existing packages, require that the
-        // scanned APK is both already known and at the path previously established
-        // for it.  Previously unknown packages we pick up normally, but if we have an
-        // a priori expectation about this package's install presence, enforce it.
-        // With a singular exception for new system packages. When an OTA contains
-        // a new system package, we allow the codepath to change from a system location
-        // to the user-installed location. If we don't allow this change, any newer,
-        // user-installed version of the application will be ignored.
-        if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
-            if (mExpectingBetter.containsKey(pkg.packageName)) {
-                logCriticalInfo(Log.WARN,
-                        "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
-            } else {
-                PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
-                if (known != null) {
-                    if (DEBUG_PACKAGE_SCANNING) {
-                        Log.d(TAG, "Examining " + pkg.codePath
-                                + " and requiring known paths " + known.codePathString
-                                + " & " + known.resourcePathString);
-                    }
-                    if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
-                            || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) {
-                        throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
-                                "Application package " + pkg.packageName
-                                + " found at " + pkg.applicationInfo.getCodePath()
-                                + " but expected at " + known.codePathString + "; ignoring.");
+            // If we're only installing presumed-existing packages, require that the
+            // scanned APK is both already known and at the path previously established
+            // for it.  Previously unknown packages we pick up normally, but if we have an
+            // a priori expectation about this package's install presence, enforce it.
+            // With a singular exception for new system packages. When an OTA contains
+            // a new system package, we allow the codepath to change from a system location
+            // to the user-installed location. If we don't allow this change, any newer,
+            // user-installed version of the application will be ignored.
+            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
+                if (mExpectingBetter.containsKey(pkg.packageName)) {
+                    logCriticalInfo(Log.WARN,
+                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
+                } else {
+                    PackageSetting known = mSettings.peekPackageLPr(pkg.packageName);
+                    if (known != null) {
+                        if (DEBUG_PACKAGE_SCANNING) {
+                            Log.d(TAG, "Examining " + pkg.codePath
+                                    + " and requiring known paths " + known.codePathString
+                                    + " & " + known.resourcePathString);
+                        }
+                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
+                                || !pkg.applicationInfo.getResourcePath().equals(
+                                known.resourcePathString)) {
+                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
+                                    "Application package " + pkg.packageName
+                                            + " found at " + pkg.applicationInfo.getCodePath()
+                                            + " but expected at " + known.codePathString
+                                            + "; ignoring.");
+                        }
                     }
                 }
             }
@@ -7208,6 +7447,11 @@
             pkg.mAdoptPermissions = null;
         }
 
+        // Getting the package setting may have a side-effect, so if we
+        // are only checking if scan would succeed, stash a copy of the
+        // old setting to restore at the end.
+        PackageSetting nonMutatedPs = null;
+
         // writer
         synchronized (mPackages) {
             if (pkg.mSharedUserId != null) {
@@ -7279,6 +7523,14 @@
                         + " was transferred to another, but its .apk remains");
             }
 
+            // See comments in nonMutatedPs declaration
+            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
+                PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName);
+                if (foundPs != null) {
+                    nonMutatedPs = new PackageSetting(foundPs);
+                }
+            }
+
             // Just create the setting, don't add it yet. For already existing packages
             // the PkgSetting exists already and doesn't have to be created.
             pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
@@ -7305,13 +7557,15 @@
                 reportSettingsProblem(Log.WARN, msg);
 
                 // Make a note of it.
-                mTransferedPackages.add(origPackage.name);
+                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
+                    mTransferedPackages.add(origPackage.name);
+                }
 
                 // No longer need to retain this.
                 pkgSetting.origPackage = null;
             }
 
-            if (realName != null) {
+            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
                 // Make a note of it.
                 mTransferedPackages.add(pkg.packageName);
             }
@@ -7413,7 +7667,7 @@
                 }
             }
 
-            if (pkg.mAdoptPermissions != null) {
+            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
                 // This package wants to adopt ownership of permissions from
                 // another package.
                 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
@@ -7537,6 +7791,33 @@
 
         ArrayList<PackageParser.Package> clientLibPkgs = null;
 
+        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
+            if (nonMutatedPs != null) {
+                synchronized (mPackages) {
+                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
+                }
+            }
+            return pkg;
+        }
+
+        // Only privileged apps and updated privileged apps can add child packages.
+        if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
+            if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) {
+                throw new PackageManagerException("Only privileged apps and updated "
+                        + "privileged apps can add child packages. Ignoring package "
+                        + pkg.packageName);
+            }
+            final int childCount = pkg.childPackages.size();
+            for (int i = 0; i < childCount; i++) {
+                PackageParser.Package childPkg = pkg.childPackages.get(i);
+                if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
+                        childPkg.packageName)) {
+                    throw new PackageManagerException("Cannot override a child package of "
+                            + "another disabled system app. Ignoring package " + pkg.packageName);
+                }
+            }
+        }
+
         // writer
         synchronized (mPackages) {
             if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -7821,7 +8102,7 @@
 
                 // Now that permission groups have a special meaning, we ignore permission
                 // groups for legacy apps to prevent unexpected behavior. In particular,
-                // permissions for one app being granted to someone just becuase they happen
+                // permissions for one app being granted to someone just becase they happen
                 // to be in a group defined by another app (before this had no implications).
                 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                     p.group = mPermissionGroups.get(p.info.group);
@@ -7990,7 +8271,7 @@
      *
      * If {@code extractLibs} is true, native libraries are extracted from the app if required.
      */
-    public void derivePackageAbi(PackageParser.Package pkg, File scanFile,
+    private void derivePackageAbi(PackageParser.Package pkg, File scanFile,
                                  String cpuAbiOverride, boolean extractLibs)
             throws PackageManagerException {
         // TODO: We can probably be smarter about this stuff. For installed apps,
@@ -8071,16 +8352,17 @@
                 if (abi32 >= 0) {
                     final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
                     if (abi64 >= 0) {
-                        pkg.applicationInfo.secondaryCpuAbi = abi;
+                        if (cpuAbiOverride == null && pkg.use32bitAbi) {
+                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
+                            pkg.applicationInfo.primaryCpuAbi = abi;
+                        } else {
+                            pkg.applicationInfo.secondaryCpuAbi = abi;
+                        }
                     } else {
                         pkg.applicationInfo.primaryCpuAbi = abi;
                     }
                 }
-                if (cpuAbiOverride != null &&
-                        cpuAbiOverride.equals(pkg.applicationInfo.secondaryCpuAbi)) {
-                    pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
-                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
-                }
+
             } else {
                 String[] abiList = (cpuAbiOverride != null) ?
                         new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
@@ -8466,6 +8748,17 @@
         }
     }
 
+    private void killPackage(PackageParser.Package pkg, String reason) {
+        // Kill the parent package
+        killApplication(pkg.packageName, pkg.applicationInfo.uid, reason);
+        // Kill the child packages
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason);
+        }
+    }
+
     private void killApplication(String pkgName, int appId, String reason) {
         // 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
@@ -8479,6 +8772,23 @@
         }
     }
 
+    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
+        // Remove the parent package setting
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps != null) {
+            removePackageLI(ps, chatty);
+        }
+        // Remove the child package setting
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            ps = (PackageSetting) childPkg.mExtras;
+            if (ps != null) {
+                removePackageLI(ps, chatty);
+            }
+        }
+    }
+
     void removePackageLI(PackageSetting ps, boolean chatty) {
         if (DEBUG_INSTALL) {
             if (chatty)
@@ -8503,8 +8813,17 @@
 
         // writer
         synchronized (mPackages) {
+            // Remove the parent package
             mPackages.remove(pkg.applicationInfo.packageName);
             cleanPackageDataStructuresLILPw(pkg, chatty);
+
+            // Remove the child packages
+            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                PackageParser.Package childPkg = pkg.childPackages.get(i);
+                mPackages.remove(childPkg.applicationInfo.packageName);
+                cleanPackageDataStructuresLILPw(childPkg, chatty);
+            }
         }
     }
 
@@ -8708,6 +9027,17 @@
     static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
     static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
 
+    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
+        // Update the parent permissions
+        updatePermissionsLPw(pkg.packageName, pkg, flags);
+        // Update the child permissions
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
+        }
+    }
+
     private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
             int flags) {
         final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
@@ -9125,7 +9455,7 @@
                 if (pkg.isUpdatedSystemApp()) {
                     final PackageSetting sysPs = mSettings
                             .getDisabledSystemPkgLPr(pkg.packageName);
-                    if (sysPs.getPermissionsState().hasInstallPermission(perm)) {
+                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
                         // If the original was granted this permission, we take
                         // that grant decision as read and propagate it to the
                         // update.
@@ -9139,16 +9469,38 @@
                         // before.  In this case we do want to allow the app to
                         // now get the new permission if the ancestral apk is
                         // privileged to get it.
-                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
-                            for (int j=0;
-                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
-                                if (perm.equals(
-                                        sysPs.pkg.requestedPermissions.get(j))) {
+                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
+                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
+                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
                                     allowed = true;
                                     break;
                                 }
                             }
                         }
+                        // Also if a privileged parent package on the system image or any of
+                        // its children requested a privileged permission, the updated child
+                        // packages can also get the permission.
+                        if (pkg.parentPackage != null) {
+                            final PackageSetting disabledSysParentPs = mSettings
+                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
+                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
+                                    && disabledSysParentPs.isPrivileged()) {
+                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
+                                    allowed = true;
+                                } else if (disabledSysParentPs.pkg.childPackages != null) {
+                                    final int count = disabledSysParentPs.pkg.childPackages.size();
+                                    for (int i = 0; i < count; i++) {
+                                        PackageParser.Package disabledSysChildPkg =
+                                                disabledSysParentPs.pkg.childPackages.get(i);
+                                        if (isPackageRequestingPermission(disabledSysChildPkg,
+                                                perm)) {
+                                            allowed = true;
+                                            break;
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
                 } else {
                     allowed = isPrivilegedApp(pkg);
@@ -9192,6 +9544,17 @@
         return allowed;
     }
 
+    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
+        final int permCount = pkg.requestedPermissions.size();
+        for (int j = 0; j < permCount; j++) {
+            String requestedPermission = pkg.requestedPermissions.get(j);
+            if (permission.equals(requestedPermission)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     final class ActivityIntentResolver
             extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
         public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
@@ -10127,16 +10490,21 @@
         mHandler.sendMessage(msg);
     }
 
-    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, int userId) {
+    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
+            int userId) {
+        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
+        sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId);
+    }
+
+    private void sendPackageAddedForUser(String packageName, boolean isSystem,
+            int appId, int userId) {
         Bundle extras = new Bundle(1);
-        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, pkgSetting.appId));
+        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId));
 
         sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                 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, 0)) {
                 // The just-installed/enabled app is bundled on the system, so presumed
                 // to be able to run automatically without needing an explicit launch.
@@ -10209,7 +10577,7 @@
         info.removedPackage = packageName;
         info.removedUsers = new int[] {userId};
         info.uid = UserHandle.getUid(userId, pkgSetting.appId);
-        info.sendBroadcast(false, false, false);
+        info.sendPackageRemovedBroadcasts();
     }
 
     private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
@@ -10306,47 +10674,103 @@
     }
 
     @Override
-    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true,
-                "setPackageSuspended for user " + userId);
+                "setPackagesSuspended for user " + userId);
 
-        // TODO: investigate and add more restrictions for suspending crucial packages.
+        if (ArrayUtils.isEmpty(packageNames)) {
+            return packageNames;
+        }
+
+        // List of package names for whom the suspended state has changed.
+        List<String> changedPackages = new ArrayList<>(packageNames.length);
+        // List of package names for whom the suspended state is not set as requested in this
+        // method.
+        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
+        for (int i = 0; i < packageNames.length; i++) {
+            String packageName = packageNames[i];
+            long callingId = Binder.clearCallingIdentity();
+            try {
+                boolean changed = false;
+                final int appId;
+                synchronized (mPackages) {
+                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+                    if (pkgSetting == null) {
+                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
+                                + "\". Skipping suspending/un-suspending.");
+                        unactionedPackages.add(packageName);
+                        continue;
+                    }
+                    appId = pkgSetting.appId;
+                    if (pkgSetting.getSuspended(userId) != suspended) {
+                        if (!canSuspendPackageForUser(packageName, userId)) {
+                            unactionedPackages.add(packageName);
+                            continue;
+                        }
+                        pkgSetting.setSuspended(suspended, userId);
+                        mSettings.writePackageRestrictionsLPr(userId);
+                        changed = true;
+                        changedPackages.add(packageName);
+                    }
+                }
+
+                if (changed && suspended) {
+                    killApplication(packageName, UserHandle.getUid(userId, appId),
+                            "suspending package");
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+        }
+
+        if (!changedPackages.isEmpty()) {
+            sendPackagesSuspendedForUser(changedPackages.toArray(
+                    new String[changedPackages.size()]), userId, suspended);
+        }
+
+        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
+                false, "isPackageSuspendedForUser for user " + userId);
+        synchronized (mPackages) {
+            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+            return pkgSetting != null && pkgSetting.getSuspended(userId);
+        }
+    }
+
+    // TODO: investigate and add more restrictions for suspending crucial packages.
+    private boolean canSuspendPackageForUser(String packageName, int userId) {
         if (isPackageDeviceAdmin(packageName, userId)) {
             Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
                     + "\": has active device admin");
             return false;
         }
 
-        long callingId = Binder.clearCallingIdentity();
-        try {
-            boolean changed = false;
-            boolean success = false;
-            int appId = -1;
-            synchronized (mPackages) {
-                final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
-                if (pkgSetting != null) {
-                    if (pkgSetting.getSuspended(userId) != suspended) {
-                        pkgSetting.setSuspended(suspended, userId);
-                        mSettings.writePackageRestrictionsLPr(userId);
-                        appId = pkgSetting.appId;
-                        changed = true;
-                    }
-                    success = true;
-                }
-            }
-
-            if (changed) {
-                sendPackagesSuspendedForUser(new String[]{packageName}, userId, suspended);
-                if (suspended) {
-                    killApplication(packageName, UserHandle.getUid(userId, appId),
-                            "suspending package");
-                }
-            }
-            return success;
-        } finally {
-            Binder.restoreCallingIdentity(callingId);
+        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
+        if (packageName.equals(activeLauncherPackageName)) {
+            Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName
+                    + "\" because it is set as the active launcher");
+            return false;
         }
+
+        return true;
+    }
+
+    private String getActiveLauncherPackageName(int userId) {
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.addCategory(Intent.CATEGORY_HOME);
+        ResolveInfo resolveInfo = resolveIntent(
+                intent,
+                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                PackageManager.MATCH_DEFAULT_ONLY,
+                userId);
+
+        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
     }
 
     @Override
@@ -10760,10 +11184,10 @@
                 mHandler.removeCallbacks(this);
                  // Result object to be returned
                 PackageInstalledInfo res = new PackageInstalledInfo();
-                res.returnCode = currentStatus;
+                res.setReturnCode(currentStatus);
                 res.uid = -1;
                 res.pkg = null;
-                res.removedInfo = new PackageRemovedInfo();
+                res.removedInfo = null;
                 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                     args.doPreInstall(res.returnCode);
                     synchronized (mInstallLock) {
@@ -10775,7 +11199,8 @@
                 // A restore should be performed at this point if (a) the install
                 // succeeded, (b) the operation is not an update, and (c) the new
                 // package has not opted out of backup participation.
-                final boolean update = res.removedInfo.removedPackage != null;
+                final boolean update = res.removedInfo != null
+                        && res.removedInfo.removedPackage != null;
                 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
                 boolean doRestore = !update
                         && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
@@ -11780,20 +12205,20 @@
             resourceFile = afterCodeFile;
 
             // Reflect the rename in scanned details
-            pkg.codePath = afterCodeFile.getAbsolutePath();
-            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
-                    pkg.baseCodePath);
-            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
-                    pkg.splitCodePaths);
+            pkg.setCodePath(afterCodeFile.getAbsolutePath());
+            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
+                    afterCodeFile, pkg.baseCodePath));
+            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
+                    afterCodeFile, pkg.splitCodePaths));
 
             // Reflect the rename in app info
-            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
-            pkg.applicationInfo.setCodePath(pkg.codePath);
-            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
-            pkg.applicationInfo.setResourcePath(pkg.codePath);
-            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
+            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+            pkg.setApplicationInfoCodePath(pkg.codePath);
+            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+            pkg.setApplicationInfoResourcePath(pkg.codePath);
+            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
 
             return true;
         }
@@ -12035,20 +12460,20 @@
             final File afterCodeFile = new File(packagePath);
 
             // Reflect the rename in scanned details
-            pkg.codePath = afterCodeFile.getAbsolutePath();
-            pkg.baseCodePath = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
-                    pkg.baseCodePath);
-            pkg.splitCodePaths = FileUtils.rewriteAfterRename(beforeCodeFile, afterCodeFile,
-                    pkg.splitCodePaths);
+            pkg.setCodePath(afterCodeFile.getAbsolutePath());
+            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
+                    afterCodeFile, pkg.baseCodePath));
+            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
+                    afterCodeFile, pkg.splitCodePaths));
 
             // Reflect the rename in app info
-            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
-            pkg.applicationInfo.setCodePath(pkg.codePath);
-            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
-            pkg.applicationInfo.setResourcePath(pkg.codePath);
-            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
+            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+            pkg.setApplicationInfoCodePath(pkg.codePath);
+            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+            pkg.setApplicationInfoResourcePath(pkg.codePath);
+            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
 
             return true;
         }
@@ -12227,13 +12652,13 @@
             }
 
             // Reflect the move in app info
-            pkg.applicationInfo.volumeUuid = pkg.volumeUuid;
-            pkg.applicationInfo.setCodePath(pkg.codePath);
-            pkg.applicationInfo.setBaseCodePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitCodePaths(pkg.splitCodePaths);
-            pkg.applicationInfo.setResourcePath(pkg.codePath);
-            pkg.applicationInfo.setBaseResourcePath(pkg.baseCodePath);
-            pkg.applicationInfo.setSplitResourcePaths(pkg.splitCodePaths);
+            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
+            pkg.setApplicationInfoCodePath(pkg.codePath);
+            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
+            pkg.setApplicationInfoResourcePath(pkg.codePath);
+            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
+            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
 
             return true;
         }
@@ -12364,25 +12789,42 @@
         int returnCode;
         String returnMsg;
         PackageRemovedInfo removedInfo;
+        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
 
         public void setError(int code, String msg) {
-            returnCode = code;
-            returnMsg = msg;
+            setReturnCode(code);
+            setReturnMessage(msg);
             Slog.w(TAG, msg);
         }
 
         public void setError(String msg, PackageParserException e) {
-            returnCode = e.error;
-            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
+            setReturnCode(e.error);
+            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
             Slog.w(TAG, msg, e);
         }
 
         public void setError(String msg, PackageManagerException e) {
             returnCode = e.error;
-            returnMsg = ExceptionUtils.getCompleteMessage(msg, e);
+            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
             Slog.w(TAG, msg, e);
         }
 
+        public void setReturnCode(int returnCode) {
+            this.returnCode = returnCode;
+            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                addedChildPackages.valueAt(i).returnCode = returnCode;
+            }
+        }
+
+        private void setReturnMessage(String returnMsg) {
+            this.returnMsg = returnMsg;
+            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                addedChildPackages.valueAt(i).returnMsg = returnMsg;
+            }
+        }
+
         // In some error cases we want to convey more info back to the observer
         String origPackage;
         String origPermission;
@@ -12400,9 +12842,6 @@
         String pkgName = pkg.packageName;
 
         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
-        // TODO: b/23350563
-        final boolean dataDirExists = Environment
-                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
 
         synchronized(mPackages) {
             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
@@ -12427,21 +12866,17 @@
             PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
                     System.currentTimeMillis(), user);
 
-            updateSettingsLI(newPackage, installerPackageName, volumeUuid, null, null, res, user);
-            prepareAppDataAfterInstall(newPackage);
+            updateSettingsLI(newPackage, installerPackageName, null, res, user);
 
-            // delete the partially installed application. the data directory will have to be
-            // restored if it was already existing
-            if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
-                // remove package from internal structures.  Note that we want deletePackageX to
-                // delete the package data and cache directories that it created in
-                // scanPackageLocked, unless those directories existed before we even tried to
-                // install.
-                deletePackageLI(pkgName, UserHandle.ALL, false, null, null,
-                        dataDirExists ? PackageManager.DELETE_KEEP_DATA : 0,
-                                res.removedInfo, true);
+            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
+                prepareAppDataAfterInstall(newPackage);
+
+            } else {
+                // Remove package from internal structures, but keep around any
+                // data that might have already existed
+                deletePackageLI(pkgName, UserHandle.ALL, false, null,
+                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
             }
-
         } catch (PackageManagerException e) {
             res.setError("Package couldn't be installed in " + pkg.codePath, e);
         }
@@ -12486,14 +12921,12 @@
     }
 
     private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags,
-            UserHandle user, String installerPackageName, String volumeUuid,
-            PackageInstalledInfo res) {
+            UserHandle user, String installerPackageName, PackageInstalledInfo res) {
         final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
 
         final PackageParser.Package oldPackage;
         final String pkgName = pkg.packageName;
         final int[] allUsers;
-        final boolean[] perUserInstalled;
 
         // First find the old package info and check signatures
         synchronized(mPackages) {
@@ -12502,22 +12935,22 @@
             if (isEphemeral && !oldIsEphemeral) {
                 // can't downgrade from full to ephemeral
                 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
-                res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
+                res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
                 return;
             }
             if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
             final PackageSetting ps = mSettings.mPackages.get(pkgName);
             if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
-                if(!checkUpgradeKeySetLP(ps, pkg)) {
+                if (!checkUpgradeKeySetLP(ps, pkg)) {
                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                             "New package not signed by keys specified by upgrade-keysets: "
-                            + pkgName);
+                                    + pkgName);
                     return;
                 }
             } else {
                 // default to original signature matching
                 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
-                    != PackageManager.SIGNATURE_MATCH) {
+                        != PackageManager.SIGNATURE_MATCH) {
                     res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                             "New package has a different signature: " + pkgName);
                     return;
@@ -12526,42 +12959,71 @@
 
             // In case of rollback, remember per-user/profile install state
             allUsers = sUserManager.getUserIds();
-            perUserInstalled = new boolean[allUsers.length];
-            for (int i = 0; i < allUsers.length; i++) {
-                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
+        }
+
+        // Update what is removed
+        res.removedInfo = new PackageRemovedInfo();
+        res.removedInfo.uid = oldPackage.applicationInfo.uid;
+        res.removedInfo.removedPackage = oldPackage.packageName;
+        res.removedInfo.isUpdate = true;
+        final int childCount = (oldPackage.childPackages != null)
+                ? oldPackage.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            boolean childPackageUpdated = false;
+            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
+            if (res.addedChildPackages != null) {
+                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
+                if (childRes != null) {
+                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
+                    childRes.removedInfo.removedPackage = childPkg.packageName;
+                    childRes.removedInfo.isUpdate = true;
+                    childPackageUpdated = true;
+                }
+            }
+            if (!childPackageUpdated) {
+                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo();
+                childRemovedRes.removedPackage = childPkg.packageName;
+                childRemovedRes.isUpdate = false;
+                childRemovedRes.dataRemoved = true;
+                synchronized (mPackages) {
+                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
+                    if (childPs != null) {
+                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
+                    }
+                }
+                if (res.removedInfo.removedChildPackages == null) {
+                    res.removedInfo.removedChildPackages = new ArrayMap<>();
+                }
+                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
             }
         }
 
         boolean sysPkg = (isSystemApp(oldPackage));
         if (sysPkg) {
             replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
-                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
+                    user, allUsers, installerPackageName, res);
         } else {
             replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags,
-                    user, allUsers, perUserInstalled, installerPackageName, volumeUuid, res);
+                    user, allUsers, installerPackageName, res);
         }
     }
 
     private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
-            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
-            String volumeUuid, PackageInstalledInfo res) {
-        String pkgName = deletedPackage.packageName;
-        boolean deletedPkg = true;
-        boolean updatedSettings = false;
-
+            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
         if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
                 + deletedPackage);
-        long origUpdateTime;
-        if (pkg.mExtras != null) {
-            origUpdateTime = ((PackageSetting)pkg.mExtras).lastUpdateTime;
-        } else {
-            origUpdateTime = 0;
-        }
+
+        String pkgName = deletedPackage.packageName;
+        boolean deletedPkg = true;
+        boolean addedPkg = false;
+
+        final long origUpdateTime = (pkg.mExtras != null)
+                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
 
         // First delete the existing package while retaining the data directory
-        if (!deletePackageLI(pkgName, null, true, null, null, PackageManager.DELETE_KEEP_DATA,
-                res.removedInfo, true)) {
+        if (!deletePackageLI(pkgName, null, true, allUsers, PackageManager.DELETE_KEEP_DATA,
+                res.removedInfo, true, pkg)) {
             // If the existing package wasn't successfully deleted
             res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
             deletedPkg = false;
@@ -12580,33 +13042,29 @@
                 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
             }
 
-            deleteCodeCacheDirsLI(pkg.volumeUuid, pkgName);
+            deleteCodeCacheDirsLI(pkg);
+
             try {
                 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
                         scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
-                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
-                        perUserInstalled, res, user);
+                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
                 prepareAppDataAfterInstall(newPackage);
-                updatedSettings = true;
+                addedPkg = true;
             } catch (PackageManagerException e) {
                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
             }
         }
 
         if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
-            // remove package from internal structures.  Note that we want deletePackageX to
-            // delete the package data and cache directories that it created in
-            // scanPackageLocked, unless those directories existed before we even tried to
-            // install.
-            if(updatedSettings) {
-                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
-                deletePackageLI(
-                        pkgName, null, true, allUsers, perUserInstalled,
-                        PackageManager.DELETE_KEEP_DATA,
-                                res.removedInfo, true);
+            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
+
+            // Revert all internal state mutations and added folders for the failed install
+            if (addedPkg) {
+                deletePackageLI(pkgName, null, true, allUsers, PackageManager.DELETE_KEEP_DATA,
+                        res.removedInfo, true, null);
             }
-            // Since we failed to install the new package we need to restore the old
-            // package that we deleted.
+
+            // Restore the old package
             if (deletedPkg) {
                 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
                 File restoreFile = new File(deletedPackage.codePath);
@@ -12624,105 +13082,139 @@
                             + e.getMessage());
                     return;
                 }
-                // Restore of old package succeeded. Update permissions.
-                // writer
+
                 synchronized (mPackages) {
-                    updatePermissionsLPw(deletedPackage.packageName, deletedPackage,
-                            UPDATE_PERMISSIONS_ALL);
-                    // can downgrade to reader
+                    // Ensure the installer package name up to date
+                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
+
+                    // Update permissions for restored package
+                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
+
                     mSettings.writeLPr();
                 }
+
                 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
             }
+        } else {
+            synchronized (mPackages) {
+                PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName);
+                if (ps != null) {
+                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
+                    if (res.removedInfo.removedChildPackages != null) {
+                        final int childCount = res.removedInfo.removedChildPackages.size();
+                        // Iterate in reverse as we may modify the collection
+                        for (int i = childCount - 1; i >= 0; i--) {
+                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
+                            if (res.addedChildPackages.containsKey(childPackageName)) {
+                                res.removedInfo.removedChildPackages.removeAt(i);
+                            } else {
+                                PackageRemovedInfo childInfo = res.removedInfo
+                                        .removedChildPackages.valueAt(i);
+                                childInfo.removedForAllUsers = mPackages.get(
+                                        childInfo.removedPackage) == null;
+                            }
+                        }
+                    }
+                }
+            }
         }
     }
 
     private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
             PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user,
-            int[] allUsers, boolean[] perUserInstalled, String installerPackageName,
-            String volumeUuid, PackageInstalledInfo res) {
+            int[] allUsers, String installerPackageName, PackageInstalledInfo res) {
         if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
                 + ", old=" + deletedPackage);
-        boolean disabledSystem = false;
-        boolean updatedSettings = false;
+
+        final boolean disabledSystem;
+
+        // Set the system/privileged flags as needed
         parseFlags |= PackageParser.PARSE_IS_SYSTEM;
-        if ((deletedPackage.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
+        if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
                 != 0) {
             parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
         }
-        String packageName = deletedPackage.packageName;
-        if (packageName == null) {
-            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
-                    "Attempt to delete null packageName.");
-            return;
-        }
-        PackageParser.Package oldPkg;
-        PackageSetting oldPkgSetting;
-        // reader
-        synchronized (mPackages) {
-            oldPkg = mPackages.get(packageName);
-            oldPkgSetting = mSettings.mPackages.get(packageName);
-            if((oldPkg == null) || (oldPkg.applicationInfo == null) ||
-                    (oldPkgSetting == null)) {
-                res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE,
-                        "Couldn't find package " + packageName + " information");
-                return;
-            }
-        }
 
-        killApplication(packageName, oldPkg.applicationInfo.uid, "replace sys pkg");
+        // Kill package processes including services, providers, etc.
+        killPackage(deletedPackage, "replace sys pkg");
 
-        res.removedInfo.uid = oldPkg.applicationInfo.uid;
-        res.removedInfo.removedPackage = packageName;
         // Remove existing system package
-        removePackageLI(oldPkgSetting, true);
-        // writer
-        synchronized (mPackages) {
-            disabledSystem = mSettings.disableSystemPackageLPw(packageName);
-            if (!disabledSystem && deletedPackage != null) {
-                // We didn't need to disable the .apk as a current system package,
-                // which means we are replacing another update that is already
-                // installed.  We need to make sure to delete the older one's .apk.
-                res.removedInfo.args = createInstallArgsForExisting(0,
-                        deletedPackage.applicationInfo.getCodePath(),
-                        deletedPackage.applicationInfo.getResourcePath(),
-                        getAppDexInstructionSets(deletedPackage.applicationInfo));
-            } else {
-                res.removedInfo.args = null;
-            }
+        removePackageLI(deletedPackage, true);
+
+        disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
+        if (!disabledSystem) {
+            // We didn't need to disable the .apk as a current system package,
+            // which means we are replacing another update that is already
+            // installed.  We need to make sure to delete the older one's .apk.
+            res.removedInfo.args = createInstallArgsForExisting(0,
+                    deletedPackage.applicationInfo.getCodePath(),
+                    deletedPackage.applicationInfo.getResourcePath(),
+                    getAppDexInstructionSets(deletedPackage.applicationInfo));
+        } else {
+            res.removedInfo.args = null;
         }
 
         // Successfully disabled the old package. Now proceed with re-installation
-        deleteCodeCacheDirsLI(pkg.volumeUuid, packageName);
+        deleteCodeCacheDirsLI(pkg);
 
-        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
-        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
+                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
 
         PackageParser.Package newPackage = null;
         try {
+            // Add the package to the internal data structures
             newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
-            if (newPackage.mExtras != null) {
-                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
-                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
-                newPkgSetting.lastUpdateTime = System.currentTimeMillis();
 
-                // is the update attempting to change shared user? that isn't going to work...
-                if (oldPkgSetting.sharedUser != newPkgSetting.sharedUser) {
-                    res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
-                            "Forbidding shared user change from " + oldPkgSetting.sharedUser
-                            + " to " + newPkgSetting.sharedUser);
-                    updatedSettings = true;
-                }
+            // Set the update and install times
+            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
+            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
+                    System.currentTimeMillis());
+
+            // Check for shared user id changes
+            String invalidPackageName = getParentOrChildPackageChangedSharedUser(
+                    deletedPackage, newPackage);
+            if (invalidPackageName != null) {
+                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
+                        "Forbidding shared user change from " + deletedPkgSetting.sharedUser
+                                + " to " + invalidPackageName);
             }
 
+            // Update the package dynamic state if succeeded
             if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-                updateSettingsLI(newPackage, installerPackageName, volumeUuid, allUsers,
-                        perUserInstalled, res, user);
-                prepareAppDataAfterInstall(newPackage);
-                updatedSettings = true;
-            }
+                // Now that the install succeeded make sure we remove data
+                // directories for any child package the update removed.
+                final int deletedChildCount = (deletedPackage.childPackages != null)
+                        ? deletedPackage.childPackages.size() : 0;
+                final int newChildCount = (newPackage.childPackages != null)
+                        ? newPackage.childPackages.size() : 0;
+                for (int i = 0; i < deletedChildCount; i++) {
+                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
+                    boolean childPackageDeleted = true;
+                    for (int j = 0; j < newChildCount; j++) {
+                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
+                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
+                            childPackageDeleted = false;
+                            break;
+                        }
+                    }
+                    if (childPackageDeleted) {
+                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
+                                deletedChildPkg.packageName);
+                        if (ps != null && res.removedInfo.removedChildPackages != null) {
+                            PackageRemovedInfo removedChildRes = res.removedInfo
+                                    .removedChildPackages.get(deletedChildPkg.packageName);
+                            removePackageDataLI(ps, allUsers, removedChildRes, 0, false);
+                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
+                        }
+                    }
+                }
 
+                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user);
+                prepareAppDataAfterInstall(newPackage);
+            }
         } catch (PackageManagerException e) {
+            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
             res.setError("Package couldn't be installed in " + pkg.codePath, e);
         }
 
@@ -12734,21 +13226,111 @@
             }
             // Add back the old system package
             try {
-                scanPackageTracedLI(oldPkg, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
+                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
             } catch (PackageManagerException e) {
                 Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
             }
-            // Restore the old system information in Settings
+
             synchronized (mPackages) {
                 if (disabledSystem) {
-                    mSettings.enableSystemPackageLPw(packageName);
+                    enableSystemPackageLPw(deletedPackage);
                 }
-                if (updatedSettings) {
-                    mSettings.setInstallerPackageName(packageName,
-                            oldPkgSetting.installerPackageName);
-                }
+
+                // Ensure the installer package name up to date
+                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
+
+                // Update permissions for restored package
+                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
+
                 mSettings.writeLPr();
             }
+
+            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
+                    + " after failed upgrade");
+        }
+    }
+
+    /**
+     * Checks whether the parent or any of the child packages have a change shared
+     * user. For a package to be a valid update the shred users of the parent and
+     * the children should match. We may later support changing child shared users.
+     * @param oldPkg The updated package.
+     * @param newPkg The update package.
+     * @return The shared user that change between the versions.
+     */
+    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
+            PackageParser.Package newPkg) {
+        // Check parent shared user
+        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
+            return newPkg.packageName;
+        }
+        // Check child shared users
+        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
+        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
+        for (int i = 0; i < newChildCount; i++) {
+            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
+            // If this child was present, did it have the same shared user?
+            for (int j = 0; j < oldChildCount; j++) {
+                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
+                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
+                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
+                    return newChildPkg.packageName;
+                }
+            }
+        }
+        return null;
+    }
+
+    private void removeNativeBinariesLI(PackageParser.Package pkg) {
+        // Remove the lib path for the parent package
+        PackageSetting ps = (PackageSetting) pkg.mExtras;
+        if (ps != null) {
+            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
+        }
+        // Remove the lib path for the child packages
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            ps = (PackageSetting) pkg.childPackages.get(i).mExtras;
+            if (ps != null) {
+                NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
+            }
+        }
+    }
+
+    private void enableSystemPackageLPw(PackageParser.Package pkg) {
+        // Enable the parent package
+        mSettings.enableSystemPackageLPw(pkg.packageName);
+        // Enable the child packages
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            mSettings.enableSystemPackageLPw(childPkg.packageName);
+        }
+    }
+
+    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
+            PackageParser.Package newPkg) {
+        // Disable the parent package (parent always replaced)
+        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
+        // Disable the child packages
+        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
+            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
+            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
+        }
+        return disabled;
+    }
+
+    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
+            String installerPackageName) {
+        // Enable the parent package
+        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
+        // Enable the child packages
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
         }
     }
 
@@ -12813,8 +13395,24 @@
     }
 
     private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
-            String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
-            UserHandle user) {
+            int[] allUsers, PackageInstalledInfo res, UserHandle user) {
+        // Update the parent package setting
+        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
+                res, user);
+        // Update the child packages setting
+        final int childCount = (newPackage.childPackages != null)
+                ? newPackage.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPackage = newPackage.childPackages.get(i);
+            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
+            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
+                    childRes.origUsers, childRes, user);
+        }
+    }
+
+    private void updateSettingsInternalLI(PackageParser.Package newPackage,
+            String installerPackageName, int[] allUsers, int[] installedForUsers,
+            PackageInstalledInfo res, UserHandle user) {
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
 
         String pkgName = newPackage.packageName;
@@ -12837,26 +13435,30 @@
             // of the package implies that the user actually wants to run that new code,
             // so we enable the package.
             PackageSetting ps = mSettings.mPackages.get(pkgName);
+            final int userId = user.getIdentifier();
             if (ps != null) {
                 if (isSystemApp(newPackage)) {
-                    // NB: implicit assumption that system package upgrades apply to all users
                     if (DEBUG_INSTALL) {
                         Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                     }
+                    // Enable system package for requested users
                     if (res.origUsers != null) {
-                        for (int userHandle : res.origUsers) {
-                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
-                                    userHandle, installerPackageName);
+                        for (int origUserId : res.origUsers) {
+                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
+                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
+                                        origUserId, installerPackageName);
+                            }
                         }
                     }
                     // Also convey the prior install/uninstall state
-                    if (allUsers != null && perUserInstalled != null) {
-                        for (int i = 0; i < allUsers.length; i++) {
+                    if (allUsers != null && installedForUsers != null) {
+                        for (int currentUserId : allUsers) {
+                            final boolean installed = ArrayUtils.contains(
+                                    installedForUsers, currentUserId);
                             if (DEBUG_INSTALL) {
-                                Slog.d(TAG, "    user " + allUsers[i]
-                                        + " => " + perUserInstalled[i]);
+                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
                             }
-                            ps.setInstalled(perUserInstalled[i], allUsers[i]);
+                            ps.setInstalled(installed, currentUserId);
                         }
                         // these install state changes will be persisted in the
                         // upcoming call to mSettings.writeLPr().
@@ -12864,7 +13466,6 @@
                 }
                 // It's implied that when a user requests installation, they want the app to be
                 // installed and enabled.
-                int userId = user.getIdentifier();
                 if (userId != UserHandle.USER_ALL) {
                     ps.setInstalled(true, userId);
                     ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
@@ -12875,7 +13476,7 @@
             res.pkg = newPackage;
             mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
             mSettings.setInstallerPackageName(pkgName, installerPackageName);
-            res.returnCode = PackageManager.INSTALL_SUCCEEDED;
+            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
             //to update install status
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
             mSettings.writeLPr();
@@ -12906,11 +13507,12 @@
         boolean replace = false;
         int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
         if (args.move != null) {
-            // moving a complete application; perfom an initial scan on the new install location
+            // moving a complete application; perform an initial scan on the new install location
             scanFlags |= SCAN_INITIAL;
         }
+
         // Result object to be returned
-        res.returnCode = PackageManager.INSTALL_SUCCEEDED;
+        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
 
         if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
 
@@ -12918,7 +13520,7 @@
         if (ephemeral && (forwardLocked || onExternal)) {
             Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
                     + " external=" + onExternal);
-            res.returnCode = PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
+            res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
             return;
         }
 
@@ -12943,6 +13545,33 @@
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
 
+        // If we are installing a clustered package add results for the children
+        if (pkg.childPackages != null) {
+            synchronized (mPackages) {
+                final int childCount = pkg.childPackages.size();
+                for (int i = 0; i < childCount; i++) {
+                    PackageParser.Package childPkg = pkg.childPackages.get(i);
+                    PackageInstalledInfo childRes = new PackageInstalledInfo();
+                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
+                    childRes.pkg = childPkg;
+                    childRes.name = childPkg.packageName;
+                    PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
+                    if (childPs != null) {
+                        childRes.origUsers = childPs.queryInstalledUsers(
+                                sUserManager.getUserIds(), true);
+                    }
+                    if ((mPackages.containsKey(childPkg.packageName))) {
+                        childRes.removedInfo = new PackageRemovedInfo();
+                        childRes.removedInfo.removedPackage = childPkg.packageName;
+                    }
+                    if (res.addedChildPackages == null) {
+                        res.addedChildPackages = new ArrayMap<>();
+                    }
+                    res.addedChildPackages.put(childPkg.packageName, childRes);
+                }
+            }
+        }
+
         // If package doesn't declare API override, mark that we have an install
         // time CPU ABI override.
         if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
@@ -12959,7 +13588,7 @@
 
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
         try {
-            pp.collectCertificates(pkg, parseFlags);
+            PackageParser.collectCertificates(pkg, parseFlags);
         } catch (PackageParserException e) {
             res.setError("Failed collect during installPackageLI", e);
             return;
@@ -12994,8 +13623,17 @@
                     if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
                 }
 
-                // Prevent apps opting out from runtime permissions
+                // Child packages are installed through the parent package
+                if (pkg.parentPackage != null) {
+                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
+                            "Package " + pkg.packageName + " is child of package "
+                                    + pkg.parentPackage.parentPackage + ". Child packages "
+                                    + "can be updated only through the parent package.");
+                    return;
+                }
+
                 if (replace) {
+                    // Prevent apps opting out from runtime permissions
                     PackageParser.Package oldPackage = mPackages.get(pkgName);
                     final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
                     final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
@@ -13007,6 +13645,15 @@
                                         + " target SDK " + oldTargetSdk + " does.");
                         return;
                     }
+
+                    // Prevent installing of child packages
+                    if (oldPackage.parentPackage != null) {
+                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
+                                "Package " + pkg.packageName + " is child of package "
+                                        + oldPackage.parentPackage + ". Child packages "
+                                        + "can be updated only through the parent package.");
+                        return;
+                    }
                 }
             }
 
@@ -13080,7 +13727,6 @@
                     }
                 }
             }
-
         }
 
         if (systemApp) {
@@ -13157,7 +13803,7 @@
 
         if (replace) {
             replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
-                    installerPackageName, volumeUuid, res);
+                    installerPackageName, res);
         } else {
             installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
                     args.user, installerPackageName, volumeUuid, res);
@@ -13167,6 +13813,17 @@
             if (ps != null) {
                 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
             }
+
+            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                PackageParser.Package childPkg = pkg.childPackages.get(i);
+                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
+                PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName);
+                if (childPs != null) {
+                    childRes.newUsers = childPs.queryInstalledUsers(
+                            sUserManager.getUserIds(), true);
+                }
+            }
         }
     }
 
@@ -13183,10 +13840,17 @@
                 MATCH_DEBUG_TRIAGED_MISSING,
                 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
 
-        mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS);
-        final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
+        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
         msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
         mHandler.sendMessage(msg);
+
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPkg = pkg.childPackages.get(i);
+            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
+            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
+            mHandler.sendMessage(msg);
+        }
     }
 
     private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
@@ -13441,6 +14105,11 @@
         });
     }
 
+    @Override
+    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
+        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
+    }
+
     private boolean isPackageDeviceAdmin(String packageName, int userId) {
         IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
@@ -13505,61 +14174,36 @@
             return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
         }
 
-        boolean removedForAllUsers = false;
-        boolean systemUpdate = false;
-
-        PackageParser.Package uninstalledPkg;
+        PackageSetting uninstalledPs = null;
 
         // for the uninstall-updates case and restricted profiles, remember the per-
-        // userhandle installed state
+        // user handle installed state
         int[] allUsers;
-        boolean[] perUserInstalled;
         synchronized (mPackages) {
-            uninstalledPkg = mPackages.get(packageName);
-            PackageSetting ps = mSettings.mPackages.get(packageName);
-            allUsers = sUserManager.getUserIds();
-            perUserInstalled = new boolean[allUsers.length];
-            for (int i = 0; i < allUsers.length; i++) {
-                perUserInstalled[i] = ps != null ? ps.getInstalled(allUsers[i]) : false;
+            uninstalledPs = mSettings.mPackages.get(packageName);
+            if (uninstalledPs == null) {
+                Slog.w(TAG, "Not removing non-existent package " + packageName);
+                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
             }
+            allUsers = sUserManager.getUserIds();
+            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
         }
 
         synchronized (mInstallLock) {
             if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
-            res = deletePackageLI(packageName, removeForUser,
-                    true, allUsers, perUserInstalled,
-                    flags | REMOVE_CHATTY, info, true);
-            systemUpdate = info.isRemovedPackageSystemUpdate;
+            res = deletePackageLI(packageName, removeForUser, true, allUsers,
+                    flags | REMOVE_CHATTY, info, true, null);
             synchronized (mPackages) {
                 if (res) {
-                    if (!systemUpdate && mPackages.get(packageName) == null) {
-                        removedForAllUsers = true;
-                    }
-                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPkg);
+                    mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg);
                 }
             }
-            if (DEBUG_REMOVE) Slog.d(TAG, "delete res: systemUpdate=" + systemUpdate
-                    + " removedForAllUsers=" + removedForAllUsers);
         }
 
         if (res) {
-            info.sendBroadcast(true, systemUpdate, removedForAllUsers);
-
-            // If the removed package was a system update, the old system package
-            // was re-enabled; we need to broadcast this information
-            if (systemUpdate) {
-                Bundle extras = new Bundle(1);
-                extras.putInt(Intent.EXTRA_UID, info.removedAppId >= 0
-                        ? info.removedAppId : info.uid);
-                extras.putBoolean(Intent.EXTRA_REPLACING, true);
-
-                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
-                        extras, 0, null, null, null);
-                sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
-                        extras, 0, null, null, null);
-                sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
-                        null, 0, packageName, null, null);
-            }
+            info.sendPackageRemovedBroadcasts();
+            info.sendSystemPackageUpdatedBroadcasts();
+            info.sendSystemPackageAppearedBroadcasts();
         }
         // Force a gc here.
         Runtime.getRuntime().gc();
@@ -13578,25 +14222,78 @@
         String removedPackage;
         int uid = -1;
         int removedAppId = -1;
+        int[] origUsers;
         int[] removedUsers = null;
         boolean isRemovedPackageSystemUpdate = false;
+        boolean isUpdate;
+        boolean dataRemoved;
+        boolean removedForAllUsers;
         // Clean up resources deleted packages.
         InstallArgs args = null;
+        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
+        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
 
-        void sendBroadcast(boolean fullRemove, boolean replacing, boolean removedForAllUsers) {
-            Bundle extras = new Bundle(1);
+        void sendPackageRemovedBroadcasts() {
+            sendPackageRemovedBroadcastInternal();
+            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
+                childInfo.sendPackageRemovedBroadcastInternal();
+            }
+        }
+
+        void sendSystemPackageUpdatedBroadcasts() {
+            if (isRemovedPackageSystemUpdate) {
+                sendSystemPackageUpdatedBroadcastsInternal();
+                final int childCount = (removedChildPackages != null)
+                        ? removedChildPackages.size() : 0;
+                for (int i = 0; i < childCount; i++) {
+                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
+                    if (childInfo.isRemovedPackageSystemUpdate) {
+                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
+                    }
+                }
+            }
+        }
+
+        void sendSystemPackageAppearedBroadcasts() {
+            final int packageCount = (appearedChildPackages != null)
+                    ? appearedChildPackages.size() : 0;
+            for (int i = 0; i < packageCount; i++) {
+                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
+                for (int userId : installedInfo.newUsers) {
+                    sendPackageAddedForUser(installedInfo.name, true,
+                            UserHandle.getAppId(installedInfo.uid), userId);
+                }
+            }
+        }
+
+        private void sendSystemPackageUpdatedBroadcastsInternal() {
+            Bundle extras = new Bundle(2);
             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
-            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, fullRemove);
-            if (replacing) {
+            extras.putBoolean(Intent.EXTRA_REPLACING, true);
+            sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage,
+                    extras, 0, null, null, null);
+            sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
+                    extras, 0, null, null, null);
+            sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null,
+                    null, 0, removedPackage, null, null);
+        }
+
+        private void sendPackageRemovedBroadcastInternal() {
+            Bundle extras = new Bundle(2);
+            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
+            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
+            if (isUpdate || isRemovedPackageSystemUpdate) {
                 extras.putBoolean(Intent.EXTRA_REPLACING, true);
             }
             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
             if (removedPackage != null) {
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
                         extras, 0, null, null, removedUsers);
-                if (fullRemove && !replacing) {
-                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, removedPackage,
-                            extras, 0, null, null, removedUsers);
+                if (dataRemoved && !isRemovedPackageSystemUpdate) {
+                    sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
+                            removedPackage, extras, 0, null, null, removedUsers);
                 }
             }
             if (removedAppId >= 0) {
@@ -13612,8 +14309,7 @@
      * make sure this flag is set for partially installed apps. If not its meaningless to
      * delete a partially installed application.
      */
-    private void removePackageDataLI(PackageSetting ps,
-            int[] allUserHandles, boolean[] perUserInstalled,
+    private void removePackageDataLI(PackageSetting ps, int[] allUserHandles,
             PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
         String packageName = ps.name;
         if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
@@ -13632,6 +14328,9 @@
         }
         if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
             removeDataDirsLI(ps.volumeUuid, packageName);
+            if (outInfo != null) {
+                outInfo.dataRemoved = true;
+            }
             schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
         }
         // writer
@@ -13673,16 +14372,16 @@
                 }
                 // make sure to preserve per-user disabled state if this removal was just
                 // a downgrade of a system app to the factory package
-                if (allUserHandles != null && perUserInstalled != null) {
+                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
                     if (DEBUG_REMOVE) {
                         Slog.d(TAG, "Propagating install state across downgrade");
                     }
-                    for (int i = 0; i < allUserHandles.length; i++) {
+                    for (int userId : allUserHandles) {
+                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
                         if (DEBUG_REMOVE) {
-                            Slog.d(TAG, "    user " + allUserHandles[i]
-                                    + " => " + perUserInstalled[i]);
+                            Slog.d(TAG, "    user " + userId + " => " + installed);
                         }
-                        ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
+                        ps.setInstalled(installed, userId);
                     }
                 }
             }
@@ -13713,56 +14412,85 @@
     /*
      * Tries to delete system package.
      */
-    private boolean deleteSystemPackageLI(PackageSetting newPs,
-            int[] allUserHandles, boolean[] perUserInstalled,
-            int flags, PackageRemovedInfo outInfo, boolean writeSettings) {
+    private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg,
+            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
+            boolean writeSettings) {
+        if (deletedPkg.parentPackage != null) {
+            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
+            return false;
+        }
+
         final boolean applyUserRestrictions
-                = (allUserHandles != null) && (perUserInstalled != null);
-        PackageSetting disabledPs = null;
+                = (allUserHandles != null) && (outInfo.origUsers != null);
+        final PackageSetting disabledPs;
         // Confirm if the system package has been updated
         // An updated system app can be deleted. This will also have to restore
         // the system pkg from system partition
         // reader
         synchronized (mPackages) {
-            disabledPs = mSettings.getDisabledSystemPkgLPr(newPs.name);
+            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPkg.packageName);
         }
-        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + newPs
+
+        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
                 + " disabledPs=" + disabledPs);
+
         if (disabledPs == null) {
-            Slog.w(TAG, "Attempt to delete unknown system package "+ newPs.name);
+            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
             return false;
         } else if (DEBUG_REMOVE) {
             Slog.d(TAG, "Deleting system pkg from data partition");
         }
+
         if (DEBUG_REMOVE) {
             if (applyUserRestrictions) {
                 Slog.d(TAG, "Remembering install states:");
-                for (int i = 0; i < allUserHandles.length; i++) {
-                    Slog.d(TAG, "   u=" + allUserHandles[i] + " inst=" + perUserInstalled[i]);
+                for (int userId : allUserHandles) {
+                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
+                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
                 }
             }
         }
+
         // Delete the updated package
         outInfo.isRemovedPackageSystemUpdate = true;
-        if (disabledPs.versionCode < newPs.versionCode) {
+        if (outInfo.removedChildPackages != null) {
+            final int childCount = (deletedPkg.childPackages != null)
+                    ? deletedPkg.childPackages.size() : 0;
+            for (int i = 0; i < childCount; i++) {
+                String childPackageName = deletedPkg.childPackages.get(i).packageName;
+                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
+                        .contains(childPackageName)) {
+                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
+                            childPackageName);
+                    if (childInfo != null) {
+                        childInfo.isRemovedPackageSystemUpdate = true;
+                    }
+                }
+            }
+        }
+
+        if (disabledPs.versionCode < deletedPs.versionCode) {
             // Delete data for downgrades
             flags &= ~PackageManager.DELETE_KEEP_DATA;
         } else {
             // Preserve data by setting flag
             flags |= PackageManager.DELETE_KEEP_DATA;
         }
-        boolean ret = deleteInstalledPackageLI(newPs, true, flags,
-                allUserHandles, perUserInstalled, outInfo, writeSettings);
+
+        boolean ret = deleteInstalledPackageLI(deletedPkg, true, flags, allUserHandles,
+                outInfo, writeSettings, disabledPs.pkg);
         if (!ret) {
             return false;
         }
+
         // writer
         synchronized (mPackages) {
             // Reinstate the old system package
-            mSettings.enableSystemPackageLPw(newPs.name);
+            enableSystemPackageLPw(disabledPs.pkg);
             // Remove any native libraries from the upgraded package.
-            NativeLibraryHelper.removeNativeBinariesLI(newPs.legacyNativeLibraryPathString);
+            removeNativeBinariesLI(deletedPkg);
         }
+
         // Install the system package
         if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
         int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM;
@@ -13774,7 +14502,8 @@
         try {
             newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null);
         } catch (PackageManagerException e) {
-            Slog.w(TAG, "Failed to restore system package " + newPs.name + ": " + e.getMessage());
+            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
+                    + e.getMessage());
             return false;
         }
 
@@ -13787,7 +14516,7 @@
             // Propagate the permissions state as we do not want to drop on the floor
             // runtime permissions. The update permissions method below will take
             // care of removing obsolete permissions and grant install permissions.
-            ps.getPermissionsState().copyFrom(newPs.getPermissionsState());
+            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
             updatePermissionsLPw(newPkg.packageName, newPkg,
                     UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
 
@@ -13795,14 +14524,14 @@
                 if (DEBUG_REMOVE) {
                     Slog.d(TAG, "Propagating install state across reinstall");
                 }
-                for (int i = 0; i < allUserHandles.length; i++) {
+                for (int userId : allUserHandles) {
+                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
                     if (DEBUG_REMOVE) {
-                        Slog.d(TAG, "    user " + allUserHandles[i]
-                                + " => " + perUserInstalled[i]);
+                        Slog.d(TAG, "    user " + userId + " => " + installed);
                     }
-                    ps.setInstalled(perUserInstalled[i], allUserHandles[i]);
+                    ps.setInstalled(installed, userId);
 
-                    mSettings.writeRuntimePermissionsForUserLPr(allUserHandles[i], false);
+                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
                 }
                 // Regardless of writeSettings we need to ensure that this restriction
                 // state propagation is persisted
@@ -13816,23 +14545,76 @@
         return true;
     }
 
-    private boolean deleteInstalledPackageLI(PackageSetting ps,
-            boolean deleteCodeAndResources, int flags,
-            int[] allUserHandles, boolean[] perUserInstalled,
-            PackageRemovedInfo outInfo, boolean writeSettings) {
-        if (outInfo != null) {
-            outInfo.uid = ps.appId;
+    private boolean deleteInstalledPackageLI(PackageParser.Package pkg,
+            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
+            PackageRemovedInfo outInfo, boolean writeSettings,
+            PackageParser.Package replacingPackage) {
+        PackageSetting ps = null;
+
+        synchronized (mPackages) {
+            pkg = mPackages.get(pkg.packageName);
+            if (pkg == null) {
+                return false;
+            }
+
+            ps = mSettings.mPackages.get(pkg.packageName);
+            if (ps == null) {
+                return false;
+            }
+
+            if (outInfo != null) {
+                outInfo.uid = ps.appId;
+            }
+
+            if (outInfo != null && outInfo.removedChildPackages != null) {
+                final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+                for (int i = 0; i < childCount; i++) {
+                    String childPackageName = ps.childPackageNames.get(i);
+                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
+                    if (childPs == null) {
+                        return false;
+                    }
+                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
+                            childPackageName);
+                    if (childInfo != null) {
+                        childInfo.uid = childPs.appId;
+                    }
+                }
+            }
         }
 
         // Delete package data from internal structures and also remove data if flag is set
-        removePackageDataLI(ps, allUserHandles, perUserInstalled, outInfo, flags, writeSettings);
+        removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings);
 
-        // Delete application code and resources
-        if (deleteCodeAndResources && (outInfo != null)) {
-            outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
-                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
-            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
+        // Delete the child packages data
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageSetting childPs;
+            synchronized (mPackages) {
+                childPs = mSettings.peekPackageLPr(pkg.childPackages.get(i).packageName);
+            }
+            if (childPs != null) {
+                PackageRemovedInfo childOutInfo = (outInfo != null
+                        && outInfo.removedChildPackages != null)
+                        ? outInfo.removedChildPackages.get(childPs.name) : null;
+                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
+                        && (replacingPackage != null
+                        && !replacingPackage.hasChildPackage(childPs.name))
+                        ? flags & ~DELETE_KEEP_DATA : flags;
+                removePackageDataLI(childPs, allUserHandles, childOutInfo,
+                        deleteFlags, writeSettings);
+            }
         }
+
+        // Delete application code and resources only for parent packages
+        if (ps.pkg.parentPackage == null) {
+            if (deleteCodeAndResources && (outInfo != null)) {
+                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
+                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
+                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
+            }
+        }
+
         return true;
     }
 
@@ -13897,128 +14679,217 @@
      * This method handles package deletion in general
      */
     private boolean deletePackageLI(String packageName, UserHandle user,
-            boolean deleteCodeAndResources, int[] allUserHandles, boolean[] perUserInstalled,
-            int flags, PackageRemovedInfo outInfo,
-            boolean writeSettings) {
+            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
+            PackageRemovedInfo outInfo, boolean writeSettings,
+            PackageParser.Package replacingPackage) {
         if (packageName == null) {
             Slog.w(TAG, "Attempt to delete null packageName.");
             return false;
         }
+
         if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
+
         PackageSetting ps;
-        boolean dataOnly = false;
-        int removeUser = -1;
-        int appId = -1;
+
         synchronized (mPackages) {
             ps = mSettings.mPackages.get(packageName);
             if (ps == null) {
                 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
                 return false;
             }
-            if ((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
-                    && user.getIdentifier() != UserHandle.USER_ALL) {
-                // The caller is asking that the package only be deleted for a single
-                // user.  To do this, we just mark its uninstalled state and delete
-                // its data.  If this is a system app, we only allow this to happen if
-                // they have set the special DELETE_SYSTEM_APP which requests different
-                // semantics than normal for uninstalling system apps.
-                if (DEBUG_REMOVE) Slog.d(TAG, "Only deleting for single user");
-                final int userId = user.getIdentifier();
-                ps.setUserState(userId,
-                        COMPONENT_ENABLED_STATE_DEFAULT,
-                        false, //installed
-                        true,  //stopped
-                        true,  //notLaunched
-                        false, //hidden
-                        false, //suspended
-                        null, null, null,
-                        false, // blockUninstall
-                        ps.readUserState(userId).domainVerificationStatus, 0);
-                if (!isSystemApp(ps)) {
-                    // Do not uninstall the APK if an app should be cached
-                    boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
-                    if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
-                        // Other user still have this package installed, so all
-                        // we need to do is clear this user's data and save that
-                        // it is uninstalled.
-                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
-                        removeUser = user.getIdentifier();
-                        appId = ps.appId;
-                        scheduleWritePackageRestrictionsLocked(removeUser);
-                    } else {
-                        // We need to set it back to 'installed' so the uninstall
-                        // broadcasts will be sent correctly.
-                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
-                        ps.setInstalled(true, user.getIdentifier());
-                    }
-                } else {
-                    // This is a system app, so we assume that the
-                    // other users still have this package installed, so all
+
+            if (ps.pkg.parentPackage != null && (!isSystemApp(ps)
+                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
+                if (DEBUG_REMOVE) {
+                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
+                            + ((user == null) ? UserHandle.USER_ALL : user));
+                }
+                final int removedUserId = (user != null) ? user.getIdentifier()
+                        : UserHandle.USER_ALL;
+                if (!clearPackageStateForUser(ps, removedUserId, outInfo)) {
+                    return false;
+                }
+                markPackageUninstalledForUserLPw(ps, user);
+                scheduleWritePackageRestrictionsLocked(user);
+                return true;
+            }
+        }
+
+        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
+                && user.getIdentifier() != UserHandle.USER_ALL)) {
+            // The caller is asking that the package only be deleted for a single
+            // user.  To do this, we just mark its uninstalled state and delete
+            // its data. If this is a system app, we only allow this to happen if
+            // they have set the special DELETE_SYSTEM_APP which requests different
+            // semantics than normal for uninstalling system apps.
+            markPackageUninstalledForUserLPw(ps, user);
+
+            if (!isSystemApp(ps)) {
+                // Do not uninstall the APK if an app should be cached
+                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
+                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
+                    // Other user still have this package installed, so all
                     // we need to do is clear this user's data and save that
                     // it is uninstalled.
-                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
-                    removeUser = user.getIdentifier();
-                    appId = ps.appId;
-                    scheduleWritePackageRestrictionsLocked(removeUser);
+                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
+                    if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
+                        return false;
+                    }
+                    scheduleWritePackageRestrictionsLocked(user);
+                    return true;
+                } else {
+                    // We need to set it back to 'installed' so the uninstall
+                    // broadcasts will be sent correctly.
+                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
+                    ps.setInstalled(true, user.getIdentifier());
                 }
+            } else {
+                // This is a system app, so we assume that the
+                // other users still have this package installed, so all
+                // we need to do is clear this user's data and save that
+                // it is uninstalled.
+                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
+                if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) {
+                    return false;
+                }
+                scheduleWritePackageRestrictionsLocked(user);
+                return true;
             }
         }
 
-        if (removeUser >= 0) {
-            // From above, we determined that we are deleting this only
-            // for a single user.  Continue the work here.
-            if (DEBUG_REMOVE) Slog.d(TAG, "Updating install state for user: " + removeUser);
-            if (outInfo != null) {
-                outInfo.removedPackage = packageName;
-                outInfo.removedAppId = appId;
-                outInfo.removedUsers = new int[] {removeUser};
-            }
-            // TODO: triage flags as part of 26466827
-            final int installerFlags = StorageManager.FLAG_STORAGE_CE
-                    | StorageManager.FLAG_STORAGE_DE;
-            try {
-                mInstaller.destroyAppData(ps.volumeUuid, packageName, removeUser, installerFlags);
-            } catch (InstallerException e) {
-                Slog.w(TAG, "Failed to delete app data", e);
-            }
-            removeKeystoreDataIfNeeded(removeUser, appId);
-            schedulePackageCleaning(packageName, removeUser, false);
+        // If we are deleting a composite package for all users, keep track
+        // of result for each child.
+        if (ps.childPackageNames != null && outInfo != null) {
             synchronized (mPackages) {
-                if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) {
-                    scheduleWritePackageRestrictionsLocked(removeUser);
+                final int childCount = ps.childPackageNames.size();
+                outInfo.removedChildPackages = new ArrayMap<>(childCount);
+                for (int i = 0; i < childCount; i++) {
+                    String childPackageName = ps.childPackageNames.get(i);
+                    PackageRemovedInfo childInfo = new PackageRemovedInfo();
+                    childInfo.removedPackage = childPackageName;
+                    outInfo.removedChildPackages.put(childPackageName, childInfo);
+                    PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
+                    if (childPs != null) {
+                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
+                    }
                 }
-                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, removeUser);
             }
-            return true;
-        }
-
-        if (dataOnly) {
-            // Delete application data first
-            if (DEBUG_REMOVE) Slog.d(TAG, "Removing package data only");
-            removePackageDataLI(ps, null, null, outInfo, flags, writeSettings);
-            return true;
         }
 
         boolean ret = false;
         if (isSystemApp(ps)) {
             if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
-            // When an updated system application is deleted we delete the existing resources as well and
-            // fall back to existing code in system partition
-            ret = deleteSystemPackageLI(ps, allUserHandles, perUserInstalled,
-                    flags, outInfo, writeSettings);
+            // When an updated system application is deleted we delete the existing resources
+            // as well and fall back to existing code in system partition
+            ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
         } else {
             if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
             // Kill application pre-emptively especially for apps on sd.
             killApplication(packageName, ps.appId, "uninstall pkg");
-            ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags,
-                    allUserHandles, perUserInstalled,
-                    outInfo, writeSettings);
+            ret = deleteInstalledPackageLI(ps.pkg, deleteCodeAndResources, flags, allUserHandles,
+                    outInfo, writeSettings, replacingPackage);
+        }
+
+        // Take a note whether we deleted the package for all users
+        if (outInfo != null) {
+            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
+            if (outInfo.removedChildPackages != null) {
+                synchronized (mPackages) {
+                    final int childCount = outInfo.removedChildPackages.size();
+                    for (int i = 0; i < childCount; i++) {
+                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
+                        if (childInfo != null) {
+                            childInfo.removedForAllUsers = mPackages.get(
+                                    childInfo.removedPackage) == null;
+                        }
+                    }
+                }
+            }
+            // If we uninstalled an update to a system app there may be some
+            // child packages that appeared as they are declared in the system
+            // app but were not declared in the update.
+            if (isSystemApp(ps)) {
+                synchronized (mPackages) {
+                    PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name);
+                    final int childCount = (updatedPs.childPackageNames != null)
+                            ? updatedPs.childPackageNames.size() : 0;
+                    for (int i = 0; i < childCount; i++) {
+                        String childPackageName = updatedPs.childPackageNames.get(i);
+                        if (outInfo.removedChildPackages == null
+                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
+                            PackageSetting childPs = mSettings.peekPackageLPr(childPackageName);
+                            if (childPs == null) {
+                                continue;
+                            }
+                            PackageInstalledInfo installRes = new PackageInstalledInfo();
+                            installRes.name = childPackageName;
+                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
+                            installRes.pkg = mPackages.get(childPackageName);
+                            installRes.uid = childPs.pkg.applicationInfo.uid;
+                            if (outInfo.appearedChildPackages == null) {
+                                outInfo.appearedChildPackages = new ArrayMap<>();
+                            }
+                            outInfo.appearedChildPackages.put(childPackageName, installRes);
+                        }
+                    }
+                }
+            }
         }
 
         return ret;
     }
 
-    private final static class ClearStorageConnection implements ServiceConnection {
+    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
+        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
+                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
+        for (int nextUserId : userIds) {
+            if (DEBUG_REMOVE) {
+                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
+            }
+            ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT,
+                    false /*installed*/, true /*stopped*/, true /*notLaunched*/,
+                    false /*hidden*/, false /*suspended*/, null, null, null,
+                    false /*blockUninstall*/,
+                    ps.readUserState(nextUserId).domainVerificationStatus, 0);
+        }
+    }
+
+    private boolean clearPackageStateForUser(PackageSetting ps, int userId,
+            PackageRemovedInfo outInfo) {
+        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
+                : new int[] {userId};
+        for (int nextUserId : userIds) {
+            if (DEBUG_REMOVE) {
+                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
+                        + nextUserId);
+            }
+            final int flags =  StorageManager.FLAG_STORAGE_CE|  StorageManager.FLAG_STORAGE_DE;
+            try {
+                mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags);
+            } catch (InstallerException e) {
+                Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e);
+                return false;
+            }
+            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
+            schedulePackageCleaning(ps.name, nextUserId, false);
+            synchronized (mPackages) {
+                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
+                    scheduleWritePackageRestrictionsLocked(nextUserId);
+                }
+                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
+            }
+        }
+
+        if (outInfo != null) {
+            outInfo.removedPackage = ps.name;
+            outInfo.removedAppId = ps.appId;
+            outInfo.removedUsers = userIds;
+        }
+
+        return true;
+    }
+
+    private final class ClearStorageConnection implements ServiceConnection {
         IMediaContainerService mContainerService;
 
         @Override
@@ -16105,15 +16976,22 @@
                 if (!checkin) {
                     pw.println("Features:");
                 }
-                Iterator<String> it = mAvailableFeatures.keySet().iterator();
-                while (it.hasNext()) {
-                    String name = it.next();
-                    if (!checkin) {
-                        pw.print("  ");
-                    } else {
+
+                for (FeatureInfo feat : mAvailableFeatures.values()) {
+                    if (checkin) {
                         pw.print("feat,");
+                        pw.print(feat.name);
+                        pw.print(",");
+                        pw.println(feat.version);
+                    } else {
+                        pw.print("  ");
+                        pw.print(feat.name);
+                        if (feat.version > 0) {
+                            pw.print(" version=");
+                            pw.print(feat.version);
+                        }
+                        pw.println();
                     }
-                    pw.println(name);
                 }
             }
 
@@ -16708,7 +17586,7 @@
 
     /*
      * Unload packages mounted on external media. This involves deleting package
-     * data from internal structures, sending broadcasts about diabled packages,
+     * data from internal structures, sending broadcasts about disabled packages,
      * gc'ing to free up references, unmounting all secure containers
      * corresponding to packages on external media, and posting a
      * UPDATED_MEDIA_STATUS message if status has been requested. Please note
@@ -16729,8 +17607,8 @@
             // Delete package internally
             PackageRemovedInfo outInfo = new PackageRemovedInfo();
             synchronized (mInstallLock) {
-                boolean res = deletePackageLI(pkgName, null, false, null, null,
-                        PackageManager.DELETE_KEEP_DATA, outInfo, false);
+                boolean res = deletePackageLI(pkgName, null, false, null,
+                        PackageManager.DELETE_KEEP_DATA, outInfo, false, null);
                 if (res) {
                     pkgList.add(pkgName);
                 } else {
@@ -16875,8 +17753,8 @@
 
                 final ApplicationInfo info = ps.pkg.applicationInfo;
                 final PackageRemovedInfo outInfo = new PackageRemovedInfo();
-                if (deletePackageLI(ps.name, null, false, null, null,
-                        PackageManager.DELETE_KEEP_DATA, outInfo, false)) {
+                if (deletePackageLI(ps.name, null, false, null,
+                        PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) {
                     unloaded.add(info);
                 } else {
                     Slog.w(TAG, "Failed to unload " + ps.codePath);
@@ -16897,8 +17775,9 @@
      * recycled.
      */
     private void reconcileUsers(String volumeUuid) {
+        // TODO: also reconcile DE directories
         final File[] files = FileUtils
-                .listFilesOrEmpty(Environment.getDataUserDirectory(volumeUuid));
+                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid));
         for (File file : files) {
             if (!file.isDirectory()) continue;
 
@@ -17027,8 +17906,8 @@
         Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
                 + Integer.toHexString(flags));
 
-        final File ceDir = Environment.getDataUserCredentialEncryptedDirectory(volumeUuid, userId);
-        final File deDir = Environment.getDataUserDeviceEncryptedDirectory(volumeUuid, userId);
+        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
+        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
 
         boolean restoreconNeeded = false;
 
@@ -17121,6 +18000,15 @@
      * left intact.
      */
     private void prepareAppDataAfterInstall(PackageParser.Package pkg) {
+        prepareAppDataAfterInstallInternal(pkg);
+        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
+        for (int i = 0; i < childCount; i++) {
+            PackageParser.Package childPackage = pkg.childPackages.get(i);
+            prepareAppDataAfterInstallInternal(childPackage);
+        }
+    }
+
+    private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) {
         final PackageSetting ps;
         synchronized (mPackages) {
             ps = mSettings.mPackages.get(pkg.packageName);
@@ -17288,6 +18176,10 @@
                 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                         "Package already moved to " + volumeUuid);
             }
+            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
+                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
+                        "Device admin cannot be moved");
+            }
 
             if (ps.frozen) {
                 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
new file mode 100644
index 0000000..a3ac514
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.app.AppGlobals;
+import android.content.Intent;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.Package;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.os.RemoteException;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
+import static com.android.server.pm.PackageManagerService.TAG;
+
+/**
+ * Class containing helper methods for the PackageManagerService.
+ *
+ * {@hide}
+ */
+public class PackageManagerServiceUtils {
+    private final static long SEVEN_DAYS_IN_MILLISECONDS = 7 * 24 * 60 * 60 * 1000;
+
+    private static ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
+        List<ResolveInfo> ris = null;
+        try {
+            ris = AppGlobals.getPackageManager().queryIntentReceivers(intent, null, 0, userId);
+        } catch (RemoteException e) {
+        }
+        ArraySet<String> pkgNames = new ArraySet<String>();
+        if (ris != null) {
+            for (ResolveInfo ri : ris) {
+                pkgNames.add(ri.activityInfo.packageName);
+            }
+        }
+        return pkgNames;
+    }
+
+    private static void filterRecentlyUsedApps(Collection<PackageParser.Package> pkgs,
+            long dexOptLRUThresholdInMills) {
+        // Filter out packages that aren't recently used.
+        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 + dexOptLRUThresholdInMills < 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 dexopt " + skipped + " of " + total);
+        }
+    }
+
+    // Sort apps by importance for dexopt ordering. Important apps are given
+    // more priority in case the device runs out of space.
+    public static List<PackageParser.Package> getPackagesForDexopt(
+            Collection<PackageParser.Package> packages,
+            PackageManagerService packageManagerService) {
+        ArrayList<PackageParser.Package> remainingPkgs = new ArrayList<>(packages);
+        LinkedList<PackageParser.Package> result = new LinkedList<>();
+
+        // Give priority to core apps.
+        for (PackageParser.Package pkg : remainingPkgs) {
+            if (pkg.coreApp) {
+                if (DEBUG_DEXOPT) {
+                    Log.i(TAG, "Adding core app " + result.size() + ": " + pkg.packageName);
+                }
+                result.add(pkg);
+            }
+        }
+        remainingPkgs.removeAll(result);
+
+        // 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 (PackageParser.Package pkg : remainingPkgs) {
+            if (pkgNames.contains(pkg.packageName)) {
+                if (DEBUG_DEXOPT) {
+                    Log.i(TAG, "Adding pre boot system app " + result.size() + ": " +
+                            pkg.packageName);
+                }
+                result.add(pkg);
+            }
+        }
+        remainingPkgs.removeAll(result);
+
+        // Filter out packages that aren't recently used, add all remaining apps.
+        // TODO: add a property to control this?
+        if (packageManagerService.isHistoricalPackageUsageAvailable()) {
+            filterRecentlyUsedApps(remainingPkgs, SEVEN_DAYS_IN_MILLISECONDS);
+        }
+        result.addAll(remainingPkgs);
+
+        // Now go ahead and also add the libraries required for these packages.
+        // TODO: Think about interleaving things.
+        Set<PackageParser.Package> dependencies = new HashSet<>();
+        for (PackageParser.Package p : result) {
+            dependencies.addAll(packageManagerService.findSharedNonSystemLibraries(p));
+        }
+        if (!dependencies.isEmpty()) {
+            // We might have packages already in `result` that are dependencies
+            // of other packages. Make sure we don't add those to the list twice.
+            dependencies.removeAll(result);
+        }
+        result.addAll(dependencies);
+
+        if (DEBUG_DEXOPT) {
+            StringBuilder sb = new StringBuilder();
+            for (PackageParser.Package pkg : result) {
+                if (sb.length() > 0) {
+                    sb.append(", ");
+                }
+                sb.append(pkg.packageName);
+            }
+            Log.i(TAG, "Packages to be dexopted: " + sb.toString());
+        }
+
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index d8845d8..abee007 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -178,12 +178,10 @@
         }
 
         try {
-            mInterface.setPackageSuspendedAsUser(packageName, suspendedState, userId);
-            ApplicationInfo appInfo = mInterface.getApplicationInfo(
-                    packageName, 0, userId);
-
+            mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
+                    userId);
             pw.println("Package " + packageName + " new suspended state: "
-                    + ((appInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0));
+                    + mInterface.isPackageSuspendedForUser(packageName, userId));
             return 0;
         } catch (RemoteException e) {
             pw.println(e.toString());
@@ -339,9 +337,17 @@
         for (int p = 0; p < count; p++) {
             FeatureInfo fi = list.get(p);
             pw.print("feature:");
-            if (fi.name != null) pw.println(fi.name);
-            else pw.println("reqGlEsVersion=0x"
+            if (fi.name != null) {
+                pw.print(fi.name);
+                if (fi.version > 0) {
+                    pw.print("=");
+                    pw.print(fi.version);
+                }
+                pw.println();
+            } else {
+                pw.println("reqGlEsVersion=0x"
                     + Integer.toHexString(fi.reqGlEsVersion));
+            }
         }
         return 0;
     }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index f106b62..e3866df 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -21,6 +21,7 @@
 import android.content.pm.PackageParser;
 
 import java.io.File;
+import java.util.List;
 
 /**
  * Settings data for a particular package we know about.
@@ -33,10 +34,11 @@
     PackageSetting(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString,
-            int pVersionCode, int pkgFlags, int privateFlags) {
+            int pVersionCode, int pkgFlags, int privateFlags, String parentPackageName,
+            List<String> childPackageNames) {
         super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
                 primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
-                pVersionCode, pkgFlags, privateFlags);
+                pVersionCode, pkgFlags, privateFlags, parentPackageName, childPackageNames);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 1117988..e5eec7e 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -28,6 +28,8 @@
 import android.util.SparseArray;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Settings base class for pending and resolved classes.
@@ -49,6 +51,9 @@
     final String name;
     final String realName;
 
+    String parentPackageName;
+    List<String> childPackageNames;
+
     /**
      * Path where this package was found on disk. For monolithic packages
      * this is path to single base APK file; for cluster packages this is
@@ -126,10 +131,14 @@
     PackageSettingBase(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString,
-            int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
+            int pVersionCode, int pkgFlags, int pkgPrivateFlags,
+            String parentPackageName, List<String> childPackageNames) {
         super(pkgFlags, pkgPrivateFlags);
         this.name = name;
         this.realName = realName;
+        this.parentPackageName = parentPackageName;
+        this.childPackageNames = (childPackageNames != null)
+                ? new ArrayList<>(childPackageNames) : null;
         init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
                 secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
     }
@@ -174,6 +183,10 @@
         volumeUuid = base.volumeUuid;
 
         keySetData = new PackageKeySetData(base.keySetData);
+
+        parentPackageName = base.parentPackageName;
+        childPackageNames = (base.childPackageNames != null)
+                ? new ArrayList<>(base.childPackageNames) : null;
     }
 
     void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
diff --git a/services/core/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java
index 9a20be7..f5c81e4 100644
--- a/services/core/java/com/android/server/pm/PackageSignatures.java
+++ b/services/core/java/com/android/server/pm/PackageSignatures.java
@@ -195,7 +195,7 @@
             for (int i=0; i<mSignatures.length; i++) {
                 if (i > 0) buf.append(", ");
                 buf.append(Integer.toHexString(
-                        System.identityHashCode(mSignatures[i])));
+                        mSignatures[i].hashCode()));
             }
         }
         buf.append("]}");
diff --git a/services/core/java/com/android/server/pm/PendingPackage.java b/services/core/java/com/android/server/pm/PendingPackage.java
index bb0dba1..da73085 100644
--- a/services/core/java/com/android/server/pm/PendingPackage.java
+++ b/services/core/java/com/android/server/pm/PendingPackage.java
@@ -17,6 +17,7 @@
 package com.android.server.pm;
 
 import java.io.File;
+import java.util.List;
 
 final class PendingPackage extends PackageSettingBase {
     final int sharedId;
@@ -24,10 +25,11 @@
     PendingPackage(String name, String realName, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, String cpuAbiOverrideString, int sharedId,
-            int pVersionCode, int pkgFlags, int pkgPrivateFlags) {
+            int pVersionCode, int pkgFlags, int pkgPrivateFlags, String parentPackageName,
+            List<String> childPackageNames) {
         super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
                 primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
-                pVersionCode, pkgFlags, pkgPrivateFlags);
+                pVersionCode, pkgFlags, pkgPrivateFlags, parentPackageName, childPackageNames);
         this.sharedId = sharedId;
     }
 }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8fa5d24..1872371 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -184,6 +184,8 @@
     private static final String TAG_SHARED_USER = "shared-user";
     private static final String TAG_RUNTIME_PERMISSIONS = "runtime-permissions";
     private static final String TAG_PERMISSIONS = "perms";
+    private static final String TAG_CHILD_PACKAGE = "child-package";
+
     private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
             "persistent-preferred-activities";
     static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
@@ -416,9 +418,23 @@
             String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi,
             int pkgFlags, int pkgPrivateFlags, UserHandle user, boolean add) {
         final String name = pkg.packageName;
+        final String parentPackageName = (pkg.parentPackage != null)
+                ? pkg.parentPackage.packageName : null;
+
+        List<String> childPackageNames = null;
+        if (pkg.childPackages != null) {
+            final int childCount = pkg.childPackages.size();
+            childPackageNames = new ArrayList<>(childCount);
+            for (int i = 0; i < childCount; i++) {
+                String childPackageName = pkg.childPackages.get(i).packageName;
+                childPackageNames.add(childPackageName);
+            }
+        }
+
         PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
                 resourcePath, legacyNativeLibraryPathString, primaryCpuAbi, secondaryCpuAbi,
-                pkg.mVersionCode, pkgFlags, pkgPrivateFlags, user, add, true /* allowInstall */);
+                pkg.mVersionCode, pkgFlags, pkgPrivateFlags, user, add, true /* allowInstall */,
+                parentPackageName, childPackageNames);
         return p;
     }
 
@@ -503,8 +519,7 @@
         return mSharedUsers.values();
     }
 
-
-    boolean disableSystemPackageLPw(String name) {
+    boolean disableSystemPackageLPw(String name, boolean replaced) {
         final PackageSetting p = mPackages.get(name);
         if(p == null) {
             Log.w(PackageManagerService.TAG, "Package " + name + " is not an installed package");
@@ -512,18 +527,20 @@
         }
         final PackageSetting dp = mDisabledSysPackages.get(name);
         // always make sure the system package code and resource paths dont change
-        if (dp == null) {
+        if (dp == null && p.pkg != null && p.pkg.isSystemApp() && !p.pkg.isUpdatedSystemApp()) {
             if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
                 p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
             }
             mDisabledSysPackages.put(name, p);
 
-            // a little trick...  when we install the new package, we don't
-            // want to modify the existing PackageSetting for the built-in
-            // version.  so at this point we need a new PackageSetting that
-            // is okay to muck with.
-            PackageSetting newp = new PackageSetting(p);
-            replacePackageLPw(name, newp);
+            if (replaced) {
+                // a little trick...  when we install the new package, we don't
+                // want to modify the existing PackageSetting for the built-in
+                // version.  so at this point we need a new PackageSetting that
+                // is okay to muck with.
+                PackageSetting newp = new PackageSetting(p);
+                replacePackageLPw(name, newp);
+            }
             return true;
         }
         return false;
@@ -542,7 +559,8 @@
         PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
                 p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
                 p.secondaryCpuAbiString, p.secondaryCpuAbiString,
-                p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags);
+                p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
+                p.parentPackageName, p.childPackageNames);
         mDisabledSysPackages.remove(name);
         return ret;
     }
@@ -556,8 +574,10 @@
     }
 
     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
-            String legacyNativeLibraryPathString, String primaryCpuAbiString, String secondaryCpuAbiString,
-            String cpuAbiOverrideString, int uid, int vc, int pkgFlags, int pkgPrivateFlags) {
+            String legacyNativeLibraryPathString, String primaryCpuAbiString,
+            String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, int vc, int
+            pkgFlags, int pkgPrivateFlags, String parentPackageName,
+            List<String> childPackageNames) {
         PackageSetting p = mPackages.get(name);
         if (p != null) {
             if (p.appId == uid) {
@@ -569,7 +589,8 @@
         }
         p = new PackageSetting(name, realName, codePath, resourcePath,
                 legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
-                cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags);
+                cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, parentPackageName,
+                childPackageNames);
         p.appId = uid;
         if (addUserIdLPw(uid, p, name)) {
             mPackages.put(name, p);
@@ -650,12 +671,16 @@
             String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
             String legacyNativeLibraryPathString, String primaryCpuAbiString,
             String secondaryCpuAbiString, int vc, int pkgFlags, int pkgPrivateFlags,
-            UserHandle installUser, boolean add, boolean allowInstall) {
+            UserHandle installUser, boolean add, boolean allowInstall, String parentPackage,
+            List<String> childPackageNames) {
         PackageSetting p = mPackages.get(name);
         UserManagerService userManager = UserManagerService.getInstance();
         if (p != null) {
             p.primaryCpuAbiString = primaryCpuAbiString;
             p.secondaryCpuAbiString = secondaryCpuAbiString;
+            if (childPackageNames != null) {
+                p.childPackageNames = new ArrayList<>(childPackageNames);
+            }
 
             if (!p.codePath.equals(codePath)) {
                 // Check to see if its a disabled system app
@@ -700,7 +725,8 @@
                 // We are consuming the data from an existing package.
                 p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
                         legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
-                        null /* cpuAbiOverrideString */, vc, pkgFlags, pkgPrivateFlags);
+                        null /* cpuAbiOverrideString */, vc, pkgFlags, pkgPrivateFlags,
+                        parentPackage, childPackageNames);
                 if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
                         + name + " is adopting original package " + origPackage.name);
                 // Note that we will retain the new package's signature so
@@ -719,7 +745,8 @@
             } else {
                 p = new PackageSetting(name, realName, codePath, resourcePath,
                         legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
-                        null /* cpuAbiOverrideString */, vc, pkgFlags, pkgPrivateFlags);
+                        null /* cpuAbiOverrideString */, vc, pkgFlags, pkgPrivateFlags,
+                        parentPackage, childPackageNames);
                 p.setTimeStamp(codePath.lastModified());
                 p.sharedUser = sharedUser;
                 // If this is not a system app, it starts out stopped.
@@ -2049,6 +2076,20 @@
         serializer.endTag(null, TAG_PERMISSIONS);
     }
 
+    void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)
+            throws IOException {
+        if (childPackageNames == null) {
+            return;
+        }
+        final int childCount = childPackageNames.size();
+        for (int i = 0; i < childCount; i++) {
+            String childPackageName = childPackageNames.get(i);
+            serializer.startTag(null, TAG_CHILD_PACKAGE);
+            serializer.attribute(null, ATTR_NAME, childPackageName);
+            serializer.endTag(null, TAG_CHILD_PACKAGE);
+        }
+    }
+
     // Note: assumed "stopped" field is already cleared in all packages.
     // Legacy reader, used to read in the old file format after an upgrade. Not used after that.
     void readStoppedLPw() {
@@ -2449,6 +2490,12 @@
             serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
         }
 
+        if (pkg.parentPackageName != null) {
+            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
+        }
+
+        writeChildPackagesLPw(serializer, pkg.childPackageNames);
+
         // If this is a shared user, the permissions will be written there.
         if (pkg.sharedUser == null) {
             writePermissionsLPr(serializer, pkg.getPermissionsState()
@@ -2506,6 +2553,13 @@
         if (pkg.volumeUuid != null) {
             serializer.attribute(null, "volumeUuid", pkg.volumeUuid);
         }
+
+        if (pkg.parentPackageName != null) {
+            serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
+        }
+
+        writeChildPackagesLPw(serializer, pkg.childPackageNames);
+
         pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
 
         writePermissionsLPr(serializer, pkg.getPermissionsState()
@@ -2798,7 +2852,8 @@
                         (SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
                         pp.legacyNativeLibraryPathString, pp.primaryCpuAbiString,
                         pp.secondaryCpuAbiString, pp.versionCode, pp.pkgFlags, pp.pkgPrivateFlags,
-                        null, true /* add */, false /* allowInstall */);
+                        null, true /* add */, false /* allowInstall */, pp.parentPackageName,
+                        pp.childPackageNames);
                 if (p == null) {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Unable to create application package for " + pp.name);
@@ -3246,6 +3301,8 @@
         String legacyCpuAbiStr = parser.getAttributeValue(null, "requiredCpuAbi");
         String legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
 
+        String parentPackageName = parser.getAttributeValue(null, "parentPackageName");
+
         String primaryCpuAbiStr = parser.getAttributeValue(null, "primaryCpuAbi");
         String secondaryCpuAbiStr = parser.getAttributeValue(null, "secondaryCpuAbi");
         String cpuAbiOverrideStr = parser.getAttributeValue(null, "cpuAbiOverride");
@@ -3275,7 +3332,8 @@
         }
         PackageSetting ps = new PackageSetting(name, realName, codePathFile,
                 new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
-                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags);
+                secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
+                parentPackageName, null);
         String timeStampStr = parser.getAttributeValue(null, "ft");
         if (timeStampStr != null) {
             try {
@@ -3324,6 +3382,12 @@
 
             if (parser.getName().equals(TAG_PERMISSIONS)) {
                 readInstallPermissionsLPr(parser, ps.getPermissionsState());
+            } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
+                String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
+                if (ps.childPackageNames == null) {
+                    ps.childPackageNames = new ArrayList<>();
+                }
+                ps.childPackageNames.add(childPackageName);
             } else {
                 PackageManagerService.reportSettingsProblem(Log.WARN,
                         "Unknown element under <updated-package>: " + parser.getName());
@@ -3363,6 +3427,7 @@
         PackageSettingBase packageSetting = null;
         String version = null;
         int versionCode = 0;
+        String parentPackageName;
         try {
             name = parser.getAttributeValue(null, ATTR_NAME);
             realName = parser.getAttributeValue(null, "realName");
@@ -3374,6 +3439,8 @@
 
             legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
 
+            parentPackageName = parser.getAttributeValue(null, "parentPackageName");
+
             legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
             primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
             secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
@@ -3494,7 +3561,7 @@
                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
                         new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
                         secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
-                        pkgPrivateFlags);
+                        pkgPrivateFlags, parentPackageName, null);
                 if (PackageManagerService.DEBUG_SETTINGS)
                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
                             + userId + " pkg=" + packageSetting);
@@ -3513,7 +3580,8 @@
                     packageSetting = new PendingPackage(name.intern(), realName, new File(
                             codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
                             primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
-                            userId, versionCode, pkgFlags, pkgPrivateFlags);
+                            userId, versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
+                            null);
                     packageSetting.setTimeStamp(timeStamp);
                     packageSetting.firstInstallTime = firstInstallTime;
                     packageSetting.lastUpdateTime = lastUpdateTime;
@@ -3575,6 +3643,7 @@
                     packageSetting.installStatus = PackageSettingBase.PKG_INSTALL_COMPLETE;
                 }
             }
+
             int outerDepth = parser.getDepth();
             int type;
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -3621,6 +3690,12 @@
                     packageSetting.keySetData.addDefinedKeySet(id, alias);
                 } else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
                     readDomainVerificationLPw(parser, packageSetting);
+                } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
+                    String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
+                    if (packageSetting.childPackageNames == null) {
+                        packageSetting.childPackageNames = new ArrayList<>();
+                    }
+                    packageSetting.childPackageNames.add(childPackageName);
                 } else {
                     PackageManagerService.reportSettingsProblem(Log.WARN,
                             "Unknown element under <package>: " + parser.getName());
@@ -3884,6 +3959,28 @@
         return mVerifierDeviceIdentity;
     }
 
+    public boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
+            String childPackageName) {
+        final int packageCount = mDisabledSysPackages.size();
+        for (int i = 0; i < packageCount; i++) {
+            PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
+            if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
+                continue;
+            }
+            if (disabledPs.name.equals(parentPackageName)) {
+                continue;
+            }
+            final int childCount = disabledPs.childPackageNames.size();
+            for (int j = 0; j < childCount; j++) {
+                String currChildPackageName = disabledPs.childPackageNames.get(j);
+                if (currChildPackageName.equals(childPackageName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     public PackageSetting getDisabledSystemPkgLPr(String name) {
         PackageSetting ps = mDisabledSysPackages.get(name);
         return ps;
@@ -4136,6 +4233,34 @@
         }
         pw.println();
         if (ps.pkg != null) {
+            if (ps.pkg.parentPackage != null) {
+                PackageParser.Package parentPkg = ps.pkg.parentPackage;
+                PackageSetting pps = mPackages.get(parentPkg.packageName);
+                if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
+                    pps = mDisabledSysPackages.get(parentPkg.packageName);
+                }
+                if (pps != null) {
+                    pw.print(prefix); pw.print("  parentPackage=");
+                    pw.println(pps.realName != null ? pps.realName : pps.name);
+                }
+            } else if (ps.pkg.childPackages != null) {
+                pw.print(prefix); pw.print("  childPackages=[");
+                final int childCount = ps.pkg.childPackages.size();
+                for (int i = 0; i < childCount; i++) {
+                    PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
+                    PackageSetting cps = mPackages.get(childPkg.packageName);
+                    if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
+                        cps = mDisabledSysPackages.get(childPkg.packageName);
+                    }
+                    if (cps != null) {
+                        if (i > 0) {
+                            pw.print(", ");
+                        }
+                        pw.print(cps.realName != null ? cps.realName : cps.name);
+                    }
+                }
+                pw.println("]");
+            }
             pw.print(prefix); pw.print("  versionName="); pw.println(ps.pkg.mVersionName);
             pw.print(prefix); pw.print("  splits="); dumpSplitNames(pw, ps.pkg); pw.println();
             pw.print(prefix); pw.print("  applicationInfo=");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3cc7b10..117c663 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1749,16 +1749,6 @@
         }
     }
 
-    private boolean isPackageInstalled(String pkg, int userId) {
-        final ApplicationInfo info = mPm.getApplicationInfo(pkg,
-                PackageManager.GET_UNINSTALLED_PACKAGES,
-                userId);
-        if (info == null || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
-            return false;
-        }
-        return true;
-    }
-
     /**
      * Removes the app restrictions file for a specific package and user id, if it exists.
      */
@@ -1789,6 +1779,10 @@
             Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
             return null;
         }
+        return createUserInternalUnchecked(name, flags, parentId);
+    }
+
+    private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) {
         if (ActivityManager.isLowRamDeviceStatic()) {
             return null;
         }
@@ -1930,13 +1924,18 @@
         if (user == null) {
             return null;
         }
-        setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
-        // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
-        // the putIntForUser() will fail.
-        android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                android.provider.Settings.Secure.LOCATION_MODE,
-                android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
-        setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
+        long identity = Binder.clearCallingIdentity();
+        try {
+            setUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS, true, user.id);
+            // Change the setting before applying the DISALLOW_SHARE_LOCATION restriction, otherwise
+            // the putIntForUser() will fail.
+            android.provider.Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    android.provider.Settings.Secure.LOCATION_MODE,
+                    android.provider.Settings.Secure.LOCATION_MODE_OFF, user.id);
+            setUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, true, user.id);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
         return user;
     }
 
@@ -2201,20 +2200,18 @@
             }
         }
 
-        if (isPackageInstalled(packageName, userId)) {
-            // Notify package of changes via an intent - only sent to explicitly registered receivers.
-            Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
-            changeIntent.setPackage(packageName);
-            changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            mContext.sendBroadcastAsUser(changeIntent, new UserHandle(userId));
-        }
+        // Notify package of changes via an intent - only sent to explicitly registered receivers.
+        Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
+        changeIntent.setPackage(packageName);
+        changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
     }
 
     private int getUidForPackage(String packageName) {
         long ident = Binder.clearCallingIdentity();
         try {
             return mContext.getPackageManager().getApplicationInfo(packageName,
-                    PackageManager.GET_UNINSTALLED_PACKAGES).uid;
+                    PackageManager.MATCH_UNINSTALLED_PACKAGES).uid;
         } catch (NameNotFoundException nnfe) {
             return -1;
         } finally {
@@ -2975,6 +2972,17 @@
                 am.switchUser(UserHandle.USER_SYSTEM);
             }
         }
+
+        @Override
+        public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
+            UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL);
+            // Keep this in sync with UserManager.createUser
+            if (user != null && !user.isAdmin()) {
+                setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
+                setUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS, true, user.id);
+            }
+            return user;
+        }
     }
 
     /* Remove all the users except of the system one. */
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index f57f75f..4b355de62 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -155,7 +155,7 @@
      */
     public static boolean isValidRestriction(@NonNull String restriction) {
         if (!USER_RESTRICTIONS.contains(restriction)) {
-            Slog.wtf(TAG, "Unknown restriction: " + restriction);
+            Slog.e(TAG, "Unknown restriction: " + restriction);
             return false;
         }
         return true;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a92cc31..e88b72f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -18,6 +18,8 @@
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -32,6 +34,7 @@
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
 
 import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.SleepToken;
 import android.app.ActivityManagerNative;
@@ -135,6 +138,7 @@
 import com.android.server.LocalServices;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate;
 import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener;
+import com.android.server.statusbar.StatusBarManagerInternal;
 
 import java.io.File;
 import java.io.FileReader;
@@ -186,8 +190,7 @@
     static final int LONG_PRESS_HOME_NOTHING = 0;
     static final int LONG_PRESS_HOME_RECENT_SYSTEM_UI = 1;
     static final int LONG_PRESS_HOME_ASSIST = 2;
-    static final int LONG_PRESS_HOME_PICTURE_IN_PICTURE = 3;
-    static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_PICTURE_IN_PICTURE;
+    static final int LAST_LONG_PRESS_HOME_BEHAVIOR = LONG_PRESS_HOME_ASSIST;
 
     static final int DOUBLE_TAP_HOME_NOTHING = 0;
     static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1;
@@ -280,6 +283,7 @@
     DreamManagerInternal mDreamManagerInternal;
     PowerManagerInternal mPowerManagerInternal;
     IStatusBarService mStatusBarService;
+    StatusBarManagerInternal mStatusBarManagerInternal;
     boolean mPreloadedRecentApps;
     final Object mServiceAquireLock = new Object();
     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
@@ -488,6 +492,13 @@
     int mResettingSystemUiFlags = 0;
     // Bits that we are currently always keeping cleared.
     int mForceClearedSystemUiFlags = 0;
+    int mLastFullscreenStackSysUiFlags;
+    int mLastDockedStackSysUiFlags;
+    final Rect mNonDockedStackBounds = new Rect();
+    final Rect mDockedStackBounds = new Rect();
+    final Rect mLastNonDockedStackBounds = new Rect();
+    final Rect mLastDockedStackBounds = new Rect();
+
     // What we last reported to system UI about whether the compatibility
     // menu needs to be displayed.
     boolean mLastFocusNeedsMenu = false;
@@ -508,6 +519,8 @@
 
     WindowState mTopFullscreenOpaqueWindowState;
     WindowState mTopFullscreenOpaqueOrDimmingWindowState;
+    WindowState mTopDockedOpaqueWindowState;
+    WindowState mTopDockedOpaqueOrDimmingWindowState;
     HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
     HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>();
     boolean mTopIsFullscreen;
@@ -844,6 +857,16 @@
         }
     }
 
+    StatusBarManagerInternal getStatusBarManagerInternal() {
+        synchronized (mServiceAquireLock) {
+            if (mStatusBarManagerInternal == null) {
+                mStatusBarManagerInternal =
+                        LocalServices.getService(StatusBarManagerInternal.class);
+            }
+            return mStatusBarManagerInternal;
+        }
+    }
+
     /*
      * We always let the sensor be switched on by default except when
      * the user has explicitly disabled sensor based rotation or when the
@@ -1326,7 +1349,7 @@
         }
     }
 
-    private void handleLongPressOnHome(int deviceId, KeyEvent event) {
+    private void handleLongPressOnHome(int deviceId) {
         if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_NOTHING) {
             return;
         }
@@ -1340,11 +1363,8 @@
             case LONG_PRESS_HOME_ASSIST:
                 launchAssistAction(null, deviceId);
                 break;
-            case LONG_PRESS_HOME_PICTURE_IN_PICTURE:
-                requestTvPictureInPicture(event);
-                break;
             default:
-                Log.w(TAG, "Not defined home long press behavior: " + mLongPressOnHomeBehavior);
+                Log.w(TAG, "Undefined home long press behavior: " + mLongPressOnHomeBehavior);
                 break;
         }
     }
@@ -2389,7 +2409,6 @@
             case TYPE_WALLPAPER:
             case TYPE_DREAM:
             case TYPE_KEYGUARD_SCRIM:
-            case TYPE_DOCK_DIVIDER:
                 return false;
             default:
                 // Hide only windows below the keyguard host window.
@@ -2645,11 +2664,7 @@
                 }
             }
         } else if (win.getAttrs().type == TYPE_DOCK_DIVIDER) {
-            if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
-                return R.anim.fade_in;
-            } else if (transit == TRANSIT_EXIT) {
-                return R.anim.fade_out;
-            }
+            return selectDockedDividerAnimationLw(win, transit);
         }
 
         if (transit == TRANSIT_PREVIEW_DONE) {
@@ -2669,6 +2684,24 @@
         return 0;
     }
 
+    private int selectDockedDividerAnimationLw(WindowState win, int transit) {
+        int insets = mWindowManagerFuncs.getDockedDividerInsetsLw();
+
+        // If the divider is behind the navigation bar, don't animate.
+        if (mNavigationBar != null
+                && (win.getFrameLw().top + insets >= mNavigationBar.getFrameLw().top
+                        || win.getFrameLw().left + insets >= mNavigationBar.getFrameLw().left)) {
+            return 0;
+        }
+        if (transit == TRANSIT_ENTER || transit == TRANSIT_SHOW) {
+            return R.anim.fade_in;
+        } else if (transit == TRANSIT_EXIT) {
+            return R.anim.fade_out;
+        } else {
+            return 0;
+        }
+    }
+
     @Override
     public void selectRotationAnimationLw(int anim[]) {
         if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
@@ -2902,7 +2935,7 @@
                 }
             } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                 if (!keyguardOn) {
-                    handleLongPressOnHome(event.getDeviceId(), event);
+                    handleLongPressOnHome(event.getDeviceId());
                 }
             }
             return -1;
@@ -4359,6 +4392,23 @@
                             + mUnrestrictedScreenWidth;
                     pf.bottom = df.bottom = of.bottom = cf.bottom = mUnrestrictedScreenTop
                             + mUnrestrictedScreenHeight;
+                } else if ((sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) != 0) {
+                    pf.left = df.left = of.left = mRestrictedScreenLeft;
+                    pf.top = df.top = of.top  = mRestrictedScreenTop;
+                    pf.right = df.right = of.right = mRestrictedScreenLeft + mRestrictedScreenWidth;
+                    pf.bottom = df.bottom = of.bottom = mRestrictedScreenTop
+                            + mRestrictedScreenHeight;
+                    if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
+                        cf.left = mDockLeft;
+                        cf.top = mDockTop;
+                        cf.right = mDockRight;
+                        cf.bottom = mDockBottom;
+                    } else {
+                        cf.left = mContentLeft;
+                        cf.top = mContentTop;
+                        cf.right = mContentRight;
+                        cf.bottom = mContentBottom;
+                    }
                 } else {
                     pf.left = df.left = of.left = cf.left = mRestrictedScreenLeft;
                     pf.top = df.top = of.top = cf.top = mRestrictedScreenTop;
@@ -4538,6 +4588,8 @@
     public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
         mTopFullscreenOpaqueWindowState = null;
         mTopFullscreenOpaqueOrDimmingWindowState = null;
+        mTopDockedOpaqueWindowState = null;
+        mTopDockedOpaqueOrDimmingWindowState = null;
         mAppsToBeHidden.clear();
         mAppsThatDismissKeyguard.clear();
         mForceStatusBar = false;
@@ -4583,7 +4635,7 @@
                 && attrs.type < FIRST_SYSTEM_WINDOW;
         final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
         final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
-
+        final int stackId = win.getStackId();
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
             if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
@@ -4632,9 +4684,7 @@
                 } else {
                     mAppsToBeHidden.add(appToken);
                 }
-                if (attrs.x == 0 && attrs.y == 0
-                        && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
-                        && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
+                if (isFullscreen(attrs) && StackId.normallyFullscreenWindows(stackId)) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
                     if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -4678,11 +4728,37 @@
                 mWinShowWhenLocked = win;
             }
         }
-        if (mTopFullscreenOpaqueOrDimmingWindowState == null
-                && win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()
-                && win.isDimming()) {
+
+        // Keep track of the window if it's dimming but not necessarily fullscreen.
+        final boolean reallyVisible = win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw();
+        if (mTopFullscreenOpaqueOrDimmingWindowState == null &&  reallyVisible
+                && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) {
             mTopFullscreenOpaqueOrDimmingWindowState = win;
         }
+
+        // We need to keep track of the top "fullscreen" opaque window for the docked stack
+        // separately, because both the "real fullscreen" opaque window and the one for the docked
+        // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
+        if (mTopDockedOpaqueWindowState == null && reallyVisible && appWindow && attached == null
+                && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) {
+            mTopDockedOpaqueWindowState = win;
+            if (mTopDockedOpaqueOrDimmingWindowState == null) {
+                mTopDockedOpaqueOrDimmingWindowState = win;
+            }
+        }
+
+        // Also keep track of any windows that are dimming but not necessarily fullscreen in the
+        // docked stack.
+        if (mTopDockedOpaqueOrDimmingWindowState == null && reallyVisible && win.isDimming()
+                && stackId == DOCKED_STACK_ID) {
+            mTopDockedOpaqueOrDimmingWindowState = win;
+        }
+    }
+
+    private boolean isFullscreen(WindowManager.LayoutParams attrs) {
+        return attrs.x == 0 && attrs.y == 0
+                && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
+                && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
     }
 
     /** {@inheritDoc} */
@@ -6824,42 +6900,52 @@
             tmpVisibility |= StatusBarManager.DISABLE_RECENT;
         }
 
-        tmpVisibility = updateLightStatusBarLw(tmpVisibility);
+        final int fullscreenVisibility = updateLightStatusBarLw(0 /* vis */,
+                mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState);
+        final int dockedVisibility = updateLightStatusBarLw(0 /* vis */,
+                mTopDockedOpaqueWindowState, mTopDockedOpaqueOrDimmingWindowState);
+        mWindowManagerFuncs.getStackBounds(HOME_STACK_ID, mNonDockedStackBounds);
+        mWindowManagerFuncs.getStackBounds(DOCKED_STACK_ID, mDockedStackBounds);
         final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
         final int diff = visibility ^ mLastSystemUiFlags;
+        final int fullscreenDiff = fullscreenVisibility ^ mLastFullscreenStackSysUiFlags;
+        final int dockedDiff = dockedVisibility ^ mLastDockedStackSysUiFlags;
         final boolean needsMenu = win.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
-        if (diff == 0 && mLastFocusNeedsMenu == needsMenu
-                && mFocusedApp == win.getAppToken()) {
+        if (diff == 0 && fullscreenDiff == 0 && dockedDiff == 0 && mLastFocusNeedsMenu == needsMenu
+                && mFocusedApp == win.getAppToken()
+                && mLastNonDockedStackBounds.equals(mNonDockedStackBounds)
+                && mLastDockedStackBounds.equals(mDockedStackBounds)) {
             return 0;
         }
         mLastSystemUiFlags = visibility;
+        mLastFullscreenStackSysUiFlags = fullscreenVisibility;
+        mLastDockedStackSysUiFlags = dockedVisibility;
         mLastFocusNeedsMenu = needsMenu;
         mFocusedApp = win.getAppToken();
+        final Rect fullscreenStackBounds = new Rect(mNonDockedStackBounds);
+        final Rect dockedStackBounds = new Rect(mDockedStackBounds);
         mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    try {
-                        IStatusBarService statusbar = getStatusBarService();
-                        if (statusbar != null) {
-                            statusbar.setSystemUiVisibility(visibility, 0xffffffff, win.toString());
-                            statusbar.topAppWindowChanged(needsMenu);
-                        }
-                    } catch (RemoteException e) {
-                        // re-acquire status bar service next time it is needed.
-                        mStatusBarService = null;
+                    StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
+                    if (statusbar != null) {
+                        statusbar.setSystemUiVisibility(visibility, fullscreenVisibility,
+                                dockedVisibility, 0xffffffff, fullscreenStackBounds,
+                                dockedStackBounds, win.toString());
+                        statusbar.topAppWindowChanged(needsMenu);
                     }
                 }
             });
         return diff;
     }
 
-    private int updateLightStatusBarLw(int vis) {
+    private int updateLightStatusBarLw(int vis, WindowState opaque, WindowState opaqueOrDimming) {
         WindowState statusColorWin = isStatusBarKeyguard() && !mHideLockScreen
                 ? mStatusBar
-                : mTopFullscreenOpaqueOrDimmingWindowState;
+                : opaqueOrDimming;
 
         if (statusColorWin != null) {
-            if (statusColorWin == mTopFullscreenOpaqueWindowState) {
+            if (statusColorWin == opaque) {
                 // If the top fullscreen-or-dimming window is also the top fullscreen, respect
                 // its light flag.
                 vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 549d2dc..8d296d5 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -22,6 +22,7 @@
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
+import com.android.server.UiThread;
 
 import java.io.PrintWriter;
 
@@ -116,8 +117,8 @@
 
     public KeyguardServiceDelegate(Context context) {
         mContext = context;
-        mScrim = createScrim(context);
-        mScrimHandler = new Handler();
+        mScrimHandler = UiThread.getHandler();
+        mScrim = createScrim(context, mScrimHandler);
     }
 
     public void bindService(Context context) {
@@ -130,7 +131,7 @@
         intent.setComponent(keyguardComponent);
 
         if (!context.bindServiceAsUser(intent, mKeyguardConnection,
-                Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
+                Context.BIND_AUTO_CREATE, mScrimHandler, UserHandle.SYSTEM)) {
             Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
             mKeyguardState.showing = false;
             mKeyguardState.showingAndNotOccluded = false;
@@ -334,8 +335,8 @@
         }
     }
 
-    private static final View createScrim(Context context) {
-        View view = new View(context);
+    private static View createScrim(Context context, Handler handler) {
+        final View view = new View(context);
 
         int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
@@ -345,14 +346,13 @@
 
         final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
         final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 stretch, stretch, type, flags, PixelFormat.TRANSLUCENT);
         lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
         lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
         lp.setTitle("KeyguardScrim");
-        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-        wm.addView(view, lp);
+        final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         // Disable pretty much everything in statusbar until keyguard comes back and we know
         // the state of the world.
         view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
@@ -360,6 +360,12 @@
                 | View.STATUS_BAR_DISABLE_RECENT
                 | View.STATUS_BAR_DISABLE_EXPAND
                 | View.STATUS_BAR_DISABLE_SEARCH);
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                wm.addView(view, lp);
+            }
+        });
         return view;
     }
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 25d646d..cbbcdae 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -16,6 +16,7 @@
 
 package com.android.server.statusbar;
 
+import android.graphics.Rect;
 import android.os.Bundle;
 
 import com.android.server.notification.NotificationDelegate;
@@ -29,4 +30,7 @@
     void showAssistDisclosure();
     void startAssist(Bundle args);
     void onCameraLaunchGestureDetected(int source);
+    void topAppWindowChanged(boolean menuVisible);
+    void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
+            Rect fullscreenBounds, Rect dockedBounds, String cause);
 }
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 90340d5..6eab8d4 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -20,6 +20,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.graphics.Rect;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -70,6 +71,10 @@
     private Object mLock = new Object();
     // encompasses lights-out mode and other flags defined on View
     private int mSystemUiVisibility = 0;
+    private int mFullscreenStackSysUiVisibility;
+    private int mDockedStackSysUiVisibility;
+    private final Rect mFullscreenStackBounds = new Rect();
+    private final Rect mDockedStackBounds = new Rect();
     private boolean mMenuVisible = false;
     private int mImeWindowVis = 0;
     private int mImeBackDisposition;
@@ -186,6 +191,19 @@
                 }
             }
         }
+
+        @Override
+        public void topAppWindowChanged(boolean menuVisible) {
+            StatusBarManagerService.this.topAppWindowChanged(menuVisible);
+        }
+
+        @Override
+        public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
+                int mask,
+                Rect fullscreenBounds, Rect dockedBounds, String cause) {
+            StatusBarManagerService.this.setSystemUiVisibility(vis, fullscreenStackVis,
+                    dockedStackVis, mask, fullscreenBounds, dockedBounds, cause);
+        }
     };
 
     // ================================================================================
@@ -390,8 +408,7 @@
      * response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set
      * to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}.
      */
-    @Override
-    public void topAppWindowChanged(final boolean menuVisible) {
+    private void topAppWindowChanged(final boolean menuVisible) {
         enforceStatusBar();
 
         if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
@@ -399,15 +416,15 @@
         synchronized(mLock) {
             mMenuVisible = menuVisible;
             mHandler.post(new Runnable() {
-                    public void run() {
-                        if (mBar != null) {
-                            try {
-                                mBar.topAppWindowChanged(menuVisible);
-                            } catch (RemoteException ex) {
-                            }
+                public void run() {
+                    if (mBar != null) {
+                        try {
+                            mBar.topAppWindowChanged(menuVisible);
+                        } catch (RemoteException ex) {
                         }
                     }
-                });
+                }
+            });
         }
     }
 
@@ -443,13 +460,19 @@
 
     @Override
     public void setSystemUiVisibility(int vis, int mask, String cause) {
+        setSystemUiVisibility(vis, 0, 0, mask, mFullscreenStackBounds, mDockedStackBounds, cause);
+    }
+
+    private void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
+            Rect fullscreenBounds, Rect dockedBounds, String cause) {
         // also allows calls from window manager which is in this process.
         enforceStatusBarService();
 
         if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
 
         synchronized (mLock) {
-            updateUiVisibilityLocked(vis, mask);
+            updateUiVisibilityLocked(vis, fullscreenStackVis, dockedStackVis, mask,
+                    fullscreenBounds, dockedBounds);
             disableLocked(
                     mCurrentUserId,
                     vis & StatusBarManager.DISABLE_MASK,
@@ -458,14 +481,25 @@
         }
     }
 
-    private void updateUiVisibilityLocked(final int vis, final int mask) {
-        if (mSystemUiVisibility != vis) {
+    private void updateUiVisibilityLocked(final int vis,
+            final int fullscreenStackVis, final int dockedStackVis, final int mask,
+            final Rect fullscreenBounds, final Rect dockedBounds) {
+        if (mSystemUiVisibility != vis
+                || mFullscreenStackSysUiVisibility != fullscreenStackVis
+                || mDockedStackSysUiVisibility != dockedStackVis
+                || !mFullscreenStackBounds.equals(fullscreenBounds)
+                || !mDockedStackBounds.equals(dockedBounds)) {
             mSystemUiVisibility = vis;
+            mFullscreenStackSysUiVisibility = fullscreenStackVis;
+            mDockedStackSysUiVisibility = dockedStackVis;
+            mFullscreenStackBounds.set(fullscreenBounds);
+            mDockedStackBounds.set(dockedBounds);
             mHandler.post(new Runnable() {
                     public void run() {
                         if (mBar != null) {
                             try {
-                                mBar.setSystemUiVisibility(vis, mask);
+                                mBar.setSystemUiVisibility(vis, fullscreenStackVis, dockedStackVis,
+                                        mask, fullscreenBounds, dockedBounds);
                             } catch (RemoteException ex) {
                             }
                         }
@@ -617,7 +651,8 @@
     // ================================================================================
     @Override
     public void registerStatusBar(IStatusBar bar, List<String> iconSlots,
-            List<StatusBarIcon> iconList, int switches[], List<IBinder> binders) {
+            List<StatusBarIcon> iconList, int switches[], List<IBinder> binders,
+            Rect fullscreenStackBounds, Rect dockedStackBounds) {
         enforceStatusBarService();
 
         Slog.i(TAG, "registerStatusBar bar=" + bar);
@@ -636,7 +671,11 @@
             switches[4] = mImeBackDisposition;
             switches[5] = mShowImeSwitcher ? 1 : 0;
             switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2);
+            switches[7] = mFullscreenStackSysUiVisibility;
+            switches[8] = mDockedStackSysUiVisibility;
             binders.add(mImeToken);
+            fullscreenStackBounds.set(mFullscreenStackBounds);
+            dockedStackBounds.set(mDockedStackBounds);
         }
     }
 
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 3e99a4c..628c627 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -19,6 +19,7 @@
 import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
 import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
 
+import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -304,9 +305,8 @@
             if (hasHardwarePermission(pm, component)) {
                 ServiceState serviceState = userState.serviceStateMap.get(component);
                 if (serviceState == null) {
-                    // We see this hardware TV input service for the first time; we need to
-                    // prepare the ServiceState object so that we can connect to the service and
-                    // let it add TvInputInfo objects to mInputList if there's any.
+                    // New hardware input found. Create a new ServiceState and connect to the
+                    // service to populate the hardware list.
                     serviceState = new ServiceState(component, userId);
                     userState.serviceStateMap.put(component, serviceState);
                     updateServiceConnectionLocked(component, userId);
@@ -437,11 +437,7 @@
         for (SessionState state : userState.sessionStateMap.values()) {
             if (state.session != null) {
                 try {
-                    if (state.isRecordingSession) {
-                        state.session.disconnect();
-                    } else {
-                        state.session.release();
-                    }
+                    state.session.release();
                 } catch (RemoteException e) {
                     Slog.e(TAG, "error in release", e);
                 }
@@ -642,11 +638,7 @@
                 if (sessionToken == userState.mainSessionToken) {
                     setMainLocked(sessionToken, false, callingUid, userId);
                 }
-                if (sessionState.isRecordingSession) {
-                    sessionState.session.disconnect();
-                } else {
-                    sessionState.session.release();
-                }
+                sessionState.session.release();
             }
         } catch (RemoteException | SessionNotFoundException e) {
             Slog.e(TAG, "error in releaseSession", e);
@@ -777,9 +769,9 @@
         }
     }
 
-    private void setTvInputInfoLocked(UserState userState, TvInputInfo inputInfo) {
+    private void updateTvInputInfoLocked(UserState userState, TvInputInfo inputInfo) {
         if (DEBUG) {
-            Slog.d(TAG, "setTvInputInfoLocked(inputInfo=" + inputInfo + ")");
+            Slog.d(TAG, "updateTvInputInfoLocked(inputInfo=" + inputInfo + ")");
         }
         String inputId = inputInfo.getId();
         TvInputState inputState = userState.inputMap.get(inputId);
@@ -787,16 +779,13 @@
             Slog.e(TAG, "failed to set input info - unknown input id " + inputId);
             return;
         }
-        if (inputState.info.equals(inputInfo)) {
-            return;
-        }
         inputState.info = inputInfo;
 
         for (ITvInputManagerCallback callback : userState.callbackSet) {
             try {
-                callback.onTvInputInfoChanged(inputInfo);
+                callback.onTvInputInfoUpdated(inputInfo);
             } catch (RemoteException e) {
-                Slog.e(TAG, "failed to report changed input info to callback", e);
+                Slog.e(TAG, "failed to report updated input info to callback", e);
             }
         }
     }
@@ -853,7 +842,7 @@
             }
         }
 
-        public void setTvInputInfo(TvInputInfo inputInfo, int userId) {
+        public void updateTvInputInfo(TvInputInfo inputInfo, int userId) {
             String inputInfoPackageName = inputInfo.getServiceInfo().packageName;
             String callingPackageName = getCallingPackageName();
             if (!TextUtils.equals(inputInfoPackageName, callingPackageName)) {
@@ -862,12 +851,12 @@
             }
 
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userId, "setTvInputInfo");
+                    Binder.getCallingUid(), userId, "updateTvInputInfo");
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
                     UserState userState = getOrCreateUserStateLocked(resolvedUserId);
-                    setTvInputInfoLocked(userState, inputInfo);
+                    updateTvInputInfoLocked(userState, inputInfo);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -1278,6 +1267,9 @@
 
                         UserState userState = getOrCreateUserStateLocked(resolvedUserId);
                         SessionState sessionState = userState.sessionStateMap.get(sessionToken);
+                        if (sessionState.isRecordingSession) {
+                            return;
+                        }
 
                         // Log the start of watch.
                         SomeArgs args = SomeArgs.obtain();
@@ -1562,27 +1554,7 @@
         }
 
         @Override
-        public void connect(IBinder sessionToken, final Uri channelUri, Bundle params, int userId) {
-            final int callingUid = Binder.getCallingUid();
-            final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
-                    userId, "connect");
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                synchronized (mLock) {
-                    try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId).connect(
-                                channelUri, params);
-                    } catch (RemoteException | SessionNotFoundException e) {
-                        Slog.e(TAG, "error in connect", e);
-                    }
-                }
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-
-        @Override
-        public void startRecording(IBinder sessionToken, int userId) {
+        public void startRecording(IBinder sessionToken, @Nullable Uri programHint, int userId) {
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
                     userId, "startRecording");
@@ -1590,7 +1562,8 @@
             try {
                 synchronized (mLock) {
                     try {
-                        getSessionLocked(sessionToken, callingUid, resolvedUserId).startRecording();
+                        getSessionLocked(sessionToken, callingUid, resolvedUserId).startRecording(
+                                programHint);
                     } catch (RemoteException | SessionNotFoundException e) {
                         Slog.e(TAG, "error in startRecording", e);
                     }
@@ -2157,21 +2130,17 @@
                 }
 
                 if (serviceState.isHardware) {
-                    List<TvInputHardwareInfo> hardwareInfoList =
-                            mTvInputHardwareManager.getHardwareList();
-                    for (TvInputHardwareInfo hardwareInfo : hardwareInfoList) {
+                    serviceState.hardwareInputList.clear();
+                    for (TvInputHardwareInfo hardware : mTvInputHardwareManager.getHardwareList()) {
                         try {
-                            serviceState.service.notifyHardwareAdded(hardwareInfo);
+                            serviceState.service.notifyHardwareAdded(hardware);
                         } catch (RemoteException e) {
                             Slog.e(TAG, "error in notifyHardwareAdded", e);
                         }
                     }
-
-                    List<HdmiDeviceInfo> deviceInfoList =
-                            mTvInputHardwareManager.getHdmiDeviceList();
-                    for (HdmiDeviceInfo deviceInfo : deviceInfoList) {
+                    for (HdmiDeviceInfo device : mTvInputHardwareManager.getHdmiDeviceList()) {
                         try {
-                            serviceState.service.notifyHdmiDeviceAdded(deviceInfo);
+                            serviceState.service.notifyHdmiDeviceAdded(device);
                         } catch (RemoteException e) {
                             Slog.e(TAG, "error in notifyHdmiDeviceAdded", e);
                         }
@@ -2474,7 +2443,8 @@
         public void onSessionEvent(String eventType, Bundle eventArgs) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onEvent(what=" + eventType + ", data=" + eventArgs + ")");
+                    Slog.d(TAG, "onEvent(eventType=" + eventType + ", eventArgs=" + eventArgs
+                            + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
@@ -2491,7 +2461,7 @@
         public void onTimeShiftStatusChanged(int status) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onTimeShiftStatusChanged()");
+                    Slog.d(TAG, "onTimeShiftStatusChanged(status=" + status + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
@@ -2508,7 +2478,7 @@
         public void onTimeShiftStartPositionChanged(long timeMs) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onTimeShiftStartPositionChanged()");
+                    Slog.d(TAG, "onTimeShiftStartPositionChanged(timeMs=" + timeMs + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
@@ -2525,7 +2495,7 @@
         public void onTimeShiftCurrentPositionChanged(long timeMs) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onTimeShiftCurrentPositionChanged()");
+                    Slog.d(TAG, "onTimeShiftCurrentPositionChanged(timeMs=" + timeMs + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
@@ -2541,36 +2511,18 @@
 
         // For the recording session only
         @Override
-        public void onConnected() {
+        public void onTuned() {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onConnected()");
+                    Slog.d(TAG, "onTuned()");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
                 }
                 try {
-                    mSessionState.client.onConnected(mSessionState.seq);
+                    mSessionState.client.onTuned(mSessionState.seq);
                 } catch (RemoteException e) {
-                    Slog.e(TAG, "error in onConnected", e);
-                }
-            }
-        }
-
-        // For the recording session only
-        @Override
-        public void onRecordingStarted() {
-            synchronized (mLock) {
-                if (DEBUG) {
-                    Slog.d(TAG, "onRecordingStarted()");
-                }
-                if (mSessionState.session == null || mSessionState.client == null) {
-                    return;
-                }
-                try {
-                    mSessionState.client.onRecordingStarted(mSessionState.seq);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "error in onRecordingStarted", e);
+                    Slog.e(TAG, "error in onTuned", e);
                 }
             }
         }
@@ -2580,7 +2532,8 @@
         public void onRecordingStopped(Uri recordedProgramUri) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onRecordingStopped()");
+                    Slog.d(TAG, "onRecordingStopped(recordedProgramUri=" + recordedProgramUri
+                            + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
@@ -2598,7 +2551,7 @@
         public void onError(int error) {
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "onError()");
+                    Slog.d(TAG, "onError(error=" + error + ")");
                 }
                 if (mSessionState.session == null || mSessionState.client == null) {
                     return;
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index c3a6f5d..f3b120f 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -29,8 +29,9 @@
 import android.os.Binder;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.provider.Settings;
-import android.provider.Settings.Secure;
+import android.provider.Settings.Global;
 import android.util.AndroidRuntimeException;
 import android.util.Slog;
 import android.webkit.IWebViewUpdateService;
@@ -90,7 +91,7 @@
                     // change provider when the new version of the package is being installed).
                     if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)
                         && intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) {
-                        synchronized(this) {
+                        synchronized(WebViewUpdateService.this) {
                             if (mCurrentWebViewPackage == null) return;
 
                             String webViewPackage = "package:" + mCurrentWebViewPackage.packageName;
@@ -141,7 +142,7 @@
                                 // only kills dependents of packages that are being removed.
                                 try {
                                     ActivityManagerNative.getDefault().killPackageDependents(
-                                        oldProviderName, getContext().getUserId());
+                                        oldProviderName, UserHandle.USER_ALL);
                                 } catch (RemoteException e) {
                                 }
                             }
@@ -209,7 +210,7 @@
         try {
             if (oldPackage != null) {
                 ActivityManagerNative.getDefault().killPackageDependents(
-                        oldPackage.packageName, getContext().getUserId());
+                        oldPackage.packageName, UserHandle.USER_ALL);
             }
         } catch (RemoteException e) {
         }
@@ -267,13 +268,13 @@
     }
 
     private static String getUserChosenWebViewProvider() {
-        return Settings.Secure.getString(AppGlobals.getInitialApplication().getContentResolver(),
-                Settings.Secure.WEBVIEW_PROVIDER);
+        return Settings.Global.getString(AppGlobals.getInitialApplication().getContentResolver(),
+                Settings.Global.WEBVIEW_PROVIDER);
     }
 
     private void updateUserSetting(String newProviderName) {
-        Settings.Secure.putString(getContext().getContentResolver(),
-                Settings.Secure.WEBVIEW_PROVIDER,
+        Settings.Global.putString(getContext().getContentResolver(),
+                Settings.Global.WEBVIEW_PROVIDER,
                 newProviderName == null ? "" : newProviderName);
     }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 7ec945d..56ae8e0 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -127,6 +127,8 @@
 
     boolean mAlwaysFocusable;
 
+    boolean mAppStopped;
+
     ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
 
     AppWindowToken(WindowManagerService _service, IApplicationToken _token,
@@ -308,9 +310,55 @@
             if (!(win.mRemoveOnExit && win.mExiting)) {
                 win.mExiting = exiting;
             }
+            // If we're no longer exiting, remove the window from destroying list
+            if (!win.mExiting && win.mDestroying) {
+                win.mDestroying = false;
+                service.mDestroySurface.remove(win);
+            }
         }
     }
 
+    // Here we destroy surfaces which have been marked as eligible by the animator, taking care
+    // to ensure the client has finished with them. If the client could still be using them
+    // we will skip destruction and try again when the client has stopped.
+    void destroySurfaces() {
+        final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) allAppWindows.clone();
+        final DisplayContentList displayList = new DisplayContentList();
+        for (int i = allWindows.size() - 1; i >= 0; i--) {
+            final WindowState win = allWindows.get(i);
+            if (!win.mDestroying) {
+                continue;
+            }
+
+            if (!mAppStopped && !win.mClientRemoveRequested) {
+                continue;
+            }
+
+            win.destroyOrSaveSurface();
+            if (win.mRemoveOnExit) {
+                win.mExiting = false;
+                service.removeWindowInnerLocked(win);
+            }
+            final DisplayContent displayContent = win.getDisplayContent();
+            if (displayContent != null && !displayList.contains(displayContent)) {
+                displayList.add(displayContent);
+            }
+            win.mDestroying = false;
+        }
+        for (int i = 0; i < displayList.size(); i++) {
+            final DisplayContent displayContent = displayList.get(i);
+            service.mLayersController.assignLayersLocked(displayContent.getWindowList());
+            displayContent.layoutNeeded = true;
+        }
+    }
+
+    // The application has stopped, so destroy any surfaces which were keeping alive
+    // in case they were still being used.
+    void notifyAppStopped() {
+        mAppStopped = true;
+        destroySurfaces();
+    }
+
     /**
      * Checks whether we should save surfaces for this app.
      *
@@ -513,6 +561,9 @@
         mFrozenBounds.remove();
         for (int i = windows.size() - 1; i >= 0; i--) {
             final WindowState win = windows.get(i);
+            if (!win.mHasSurface) {
+                continue;
+            }
             win.mLayoutNeeded = true;
             win.setDisplayLayoutNeeded();
             if (!service.mResizingWindows.contains(win)) {
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 1bfdcce..f0efebe 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -22,9 +22,9 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.graphics.Rect;
+import android.os.Debug;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.animation.LinearInterpolator;
@@ -40,9 +40,13 @@
  * The object that is resized needs to implement {@link AnimateBoundsUser} interface.
  */
 public class BoundsAnimationController {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "BoundsAnimationController" : TAG_WM;
+    private static final boolean DEBUG_LOCAL = false;
+    private static final boolean DEBUG = DEBUG_LOCAL || DEBUG_ANIM;
+    private static final String TAG = TAG_WITH_CLASS_NAME || DEBUG_LOCAL
+            ? "BoundsAnimationController" : TAG_WM;
+    private static final int DEBUG_ANIMATION_SLOW_DOWN_FACTOR = 1;
 
-    // Only acccessed on UI thread.
+    // Only accessed on UI thread.
     private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>();
 
     private final class BoundsAnimator extends ValueAnimator
@@ -52,14 +56,22 @@
         private final Rect mTo;
         private final Rect mTmpRect;
         private final boolean mMoveToFullScreen;
+        // True if this this animation was cancelled and will be replaced the another animation from
+        // the same {@link #AnimateBoundsUser} target.
+        private boolean mWillReplace;
+        // True to true if this animation replaced a previous animation of the same
+        // {@link #AnimateBoundsUser} target.
+        private final boolean mReplacement;
 
-        BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to, boolean moveToFullScreen) {
+        BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to,
+                boolean moveToFullScreen, boolean replacement) {
             super();
             mTarget = target;
             mFrom = from;
             mTo = to;
             mTmpRect = new Rect();
             mMoveToFullScreen = moveToFullScreen;
+            mReplacement = replacement;
             addUpdateListener(this);
             addListener(this);
         }
@@ -68,13 +80,13 @@
         public void onAnimationUpdate(ValueAnimator animation) {
             final float value = (Float) animation.getAnimatedValue();
             final float remains = 1 - value;
-            mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value);
-            mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value);
-            mTmpRect.right = (int) (mFrom.right * remains + mTo.right * value);
-            mTmpRect.bottom = (int) (mFrom.bottom * remains + mTo.bottom * value);
-            if (DEBUG_ANIM) Slog.d(TAG, "animateUpdate: mTarget=" + mTarget + ", mBounds="
-                    + mTmpRect + ", from=" + mFrom + ", mTo=" + mTo + ", value=" + value
-                    + ", remains=" + remains);
+            mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value + 0.5f);
+            mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f);
+            mTmpRect.right = (int) (mFrom.right * remains + mTo.right * value + 0.5f);
+            mTmpRect.bottom = (int) (mFrom.bottom * remains + mTo.bottom * value + 0.5f);
+            if (DEBUG) Slog.d(TAG, "animateUpdate: mTarget=" + mTarget + " mBounds="
+                    + mTmpRect + " from=" + mFrom + " mTo=" + mTo + " value=" + value
+                    + " remains=" + remains);
             if (!mTarget.setSize(mTmpRect)) {
                 // Whoops, the target doesn't feel like animating anymore. Let's immediately finish
                 // any further animation.
@@ -85,13 +97,19 @@
 
         @Override
         public void onAnimationStart(Animator animation) {
-
+            if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
+                    + " mReplacement=" + mReplacement);
+            if (!mReplacement) {
+                mTarget.onAnimationStart();
+            }
         }
 
         @Override
         public void onAnimationEnd(Animator animation) {
+            if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
+                    + " mMoveToFullScreen=" + mMoveToFullScreen + " mWillReplace=" + mWillReplace);
             finishAnimation();
-            if (mMoveToFullScreen) {
+            if (mMoveToFullScreen && !mWillReplace) {
                 mTarget.moveToFullscreen();
             }
         }
@@ -101,8 +119,24 @@
             finishAnimation();
         }
 
+        @Override
+        public void cancel() {
+            mWillReplace = true;
+            if (DEBUG) Slog.d(TAG, "cancel: willReplace mTarget=" + mTarget);
+            super.cancel();
+        }
+
+        /** Returns true if the animation target is the same as the input bounds. */
+        public boolean isAnimatingTo(Rect bounds) {
+            return mTo.equals(bounds);
+        }
+
         private void finishAnimation() {
-            mTarget.finishBoundsAnimation();
+            if (DEBUG) Slog.d(TAG, "finishAnimation: mTarget=" + mTarget
+                    + " callers" + Debug.getCallers(2));
+            if (!mWillReplace) {
+                mTarget.onAnimationEnd();
+            }
             removeListener(this);
             removeUpdateListener(this);
             mRunningAnimations.remove(mTarget);
@@ -126,11 +160,13 @@
          */
         boolean setSize(Rect bounds);
 
+        void onAnimationStart();
+
         /**
-         * Callback for the target to inform it that the animation is finished, so it can do some
+         * Callback for the target to inform it that the animation has ended, so it can do some
          * necessary cleanup.
          */
-        void finishBoundsAnimation();
+        void onAnimationEnd();
 
         void moveToFullscreen();
 
@@ -146,13 +182,26 @@
         }
 
         final BoundsAnimator existing = mRunningAnimations.get(target);
-        if (existing != null) {
+        final boolean replacing = existing != null;
+
+        if (DEBUG) Slog.d(TAG, "animateBounds: target=" + target + " from=" + from + " to=" + to
+                + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing);
+
+        if (replacing) {
+            if (existing.isAnimatingTo(to)) {
+                // Just les the current animation complete if it has the same destination as the
+                // one we are trying to start.
+                if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
+                        + " ignoring...");
+                return;
+            }
             existing.cancel();
         }
-        BoundsAnimator animator = new BoundsAnimator(target, from, to, moveToFullscreen);
+        final BoundsAnimator animator =
+                new BoundsAnimator(target, from, to, moveToFullscreen, replacing);
         mRunningAnimations.put(target, animator);
         animator.setFloatValues(0f, 1f);
-        animator.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+        animator.setDuration(DEFAULT_APP_TRANSITION_DURATION * DEBUG_ANIMATION_SLOW_DOWN_FACTOR);
         animator.setInterpolator(new LinearInterpolator());
         animator.start();
     }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0c429e5..144d7ac 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -19,6 +19,9 @@
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP;
@@ -607,4 +610,39 @@
         final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
         return (stack != null && stack.isVisibleLocked()) ? stack : null;
     }
+
+    /**
+     * Find the visible, touch-deliverable window under the given point
+     */
+    WindowState getTouchableWinAtPointLocked(float xf, float yf) {
+        WindowState touchedWin = null;
+        final int x = (int) xf;
+        final int y = (int) yf;
+
+        for (int i = mWindows.size() - 1; i >= 0; i--) {
+            WindowState window = mWindows.get(i);
+            final int flags = window.mAttrs.flags;
+            if (!window.isVisibleLw()) {
+                continue;
+            }
+            if ((flags & FLAG_NOT_TOUCHABLE) != 0) {
+                continue;
+            }
+
+            window.getVisibleBounds(mTmpRect);
+            if (!mTmpRect.contains(x, y)) {
+                continue;
+            }
+
+            window.getTouchableRegion(mTmpRegion);
+
+            final int touchFlags = flags & (FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCH_MODAL);
+            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
+                touchedWin = window;
+                break;
+            }
+        }
+
+        return touchedWin;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 7295318..75c06ff 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -27,6 +27,8 @@
 
 import com.android.server.wm.DimLayer.DimLayerUser;
 
+import java.util.ArrayList;
+
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.view.WindowManager.DOCKED_BOTTOM;
@@ -72,8 +74,22 @@
         return mDividerWindowWidth - 2 * mDividerInsets;
     }
 
+    int getContentInsets() {
+        return mDividerInsets;
+    }
+
     void setResizing(boolean resizing) {
-        mResizing = resizing;
+        if (mResizing != resizing) {
+            mResizing = resizing;
+            resetDragResizingChangeReported();
+        }
+    }
+
+    private void resetDragResizingChangeReported() {
+        final WindowList windowList = mDisplayContent.getWindowList();
+        for (int i = windowList.size() - 1; i >= 0; i--) {
+            windowList.get(i).resetDragResizingChangeReported();
+        }
     }
 
     void setWindow(WindowState window) {
@@ -86,7 +102,9 @@
             return;
         }
         TaskStack stack = mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID);
-        final boolean visible = stack != null && stack.isVisibleLocked();
+
+        // If the stack is invisible, we policy force hide it in WindowAnimator.shouldForceHide
+        final boolean visible = stack != null;
         if (mLastVisibility == visible && !force) {
             return;
         }
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index d1c0881..cf27b97 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -24,15 +24,18 @@
 
 import android.content.ClipData;
 import android.content.ClipDescription;
+import android.content.Context;
 import android.graphics.Matrix;
 import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.Region;
 import android.hardware.input.InputManager;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.IUserManager;
 import android.util.Slog;
 import android.view.Display;
 import android.view.DragEvent;
@@ -66,6 +69,13 @@
 class DragState {
     private static final long ANIMATION_DURATION_MS = 500;
 
+    private static final int DRAG_FLAGS_URI_ACCESS = View.DRAG_FLAG_GLOBAL_URI_READ |
+            View.DRAG_FLAG_GLOBAL_URI_WRITE;
+
+    private static final int DRAG_FLAGS_URI_PERMISSIONS = DRAG_FLAGS_URI_ACCESS |
+            View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION |
+            View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;
+
     final WindowManagerService mService;
     IBinder mToken;
     SurfaceControl mSurfaceControl;
@@ -73,6 +83,8 @@
     IBinder mLocalWin;
     int mPid;
     int mUid;
+    int mSourceUserId;
+    boolean mCrossProfileCopyAllowed;
     ClipData mData;
     ClipDescription mDataDescription;
     int mTouchSource;
@@ -88,10 +100,7 @@
     WindowState mTargetWindow;
     ArrayList<WindowState> mNotifiedWindows;
     boolean mDragInProgress;
-    Display mDisplay;
-
-    private final Region mTmpRegion = new Region();
-    private final Rect mTmpRect = new Rect();
+    DisplayContent mDisplayContent;
 
     private Animation mAnimation;
     final Transformation mTransformation = new Transformation();
@@ -124,11 +133,12 @@
      * @param display The Display that the window being dragged is on.
      */
     void register(Display display) {
-        mDisplay = display;
         if (DEBUG_DRAG) Slog.d(TAG_WM, "registering drag input channel");
         if (mClientChannel != null) {
             Slog.e(TAG_WM, "Duplicate register of drag input channel");
         } else {
+            mDisplayContent = mService.getDisplayContentLocked(display.getDisplayId());
+
             InputChannel[] channels = InputChannel.openInputChannelPair("drag");
             mServerChannel = channels[0];
             mClientChannel = channels[1];
@@ -142,7 +152,7 @@
                     WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
 
             mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null,
-                    mDisplay.getDisplayId());
+                    display.getDisplayId());
             mDragWindowHandle.name = "drag";
             mDragWindowHandle.inputChannel = mServerChannel;
             mDragWindowHandle.layer = getDragLayerLw();
@@ -167,7 +177,7 @@
             mDragWindowHandle.frameLeft = 0;
             mDragWindowHandle.frameTop = 0;
             Point p = new Point();
-            mDisplay.getRealSize(p);
+            display.getRealSize(p);
             mDragWindowHandle.frameRight = p.x;
             mDragWindowHandle.frameBottom = p.y;
 
@@ -221,20 +231,30 @@
         mNotifiedWindows.clear();
         mDragInProgress = true;
 
+        mSourceUserId = UserHandle.getUserId(mUid);
+
+        final IUserManager userManager =
+                (IUserManager) ServiceManager.getService(Context.USER_SERVICE);
+        try {
+            mCrossProfileCopyAllowed = !userManager.getUserRestrictions(mSourceUserId).getBoolean(
+                    UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+        } catch (RemoteException e) {
+            Slog.e(TAG_WM, "Remote Exception calling UserManager: " + e);
+            mCrossProfileCopyAllowed = false;
+        }
+
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
         }
 
-        final WindowList windows = mService.getWindowListLocked(mDisplay);
-        if (windows != null) {
-            final int N = windows.size();
-            for (int i = 0; i < N; i++) {
-                sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
-            }
+        final WindowList windows = mDisplayContent.getWindowList();
+        final int N = windows.size();
+        for (int i = 0; i < N; i++) {
+            sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
         }
     }
 
-    /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
+    /* helper - send a ACTION_DRAG_STARTED event, if the
      * designated window is potentially a drop recipient.  There are race situations
      * around DRAG_ENDED broadcast, so we make sure that once we've declared that
      * the drag has ended, we never send out another DRAG_STARTED for this drag action.
@@ -244,19 +264,7 @@
      */
     private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
             ClipDescription desc) {
-        // Don't actually send the event if the drag is supposed to be pinned
-        // to the originating window but 'newWin' is not that window.
-        if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
-            final IBinder winBinder = newWin.mClient.asBinder();
-            if (winBinder != mLocalWin) {
-                if (DEBUG_DRAG) {
-                    Slog.d(TAG_WM, "Not dispatching local DRAG_STARTED to " + newWin);
-                }
-                return;
-            }
-        }
-
-        if (mDragInProgress && newWin.isPotentialDragTarget()) {
+        if (mDragInProgress && isValidDropTarget(newWin)) {
             DragEvent event = obtainDragEvent(newWin, DragEvent.ACTION_DRAG_STARTED,
                     touchX, touchY, null, desc, null, null, false);
             try {
@@ -274,17 +282,33 @@
         }
     }
 
-    /* helper - construct and send a DRAG_STARTED event only if the window has not
+    private boolean isValidDropTarget(WindowState targetWin) {
+        if (targetWin == null) {
+            return false;
+        }
+        if (!targetWin.isPotentialDragTarget()) {
+            return false;
+        }
+        if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
+            // Drag is limited to the current window.
+            if (mLocalWin != targetWin.mClient.asBinder()) {
+                return false;
+            }
+        }
+
+        return mCrossProfileCopyAllowed ||
+                mSourceUserId == UserHandle.getUserId(targetWin.getOwningUid());
+    }
+
+    /* helper - send a ACTION_DRAG_STARTED event only if the window has not
      * previously been notified, i.e. it became visible after the drag operation
      * was begun.  This is a rare case.
      */
     void sendDragStartedIfNeededLw(WindowState newWin) {
         if (mDragInProgress) {
             // If we have sent the drag-started, we needn't do so again
-            for (WindowState ws : mNotifiedWindows) {
-                if (ws == newWin) {
-                    return;
-                }
+            if (isWindowNotified(newWin)) {
+                return;
             }
             if (DEBUG_DRAG) {
                 Slog.d(TAG_WM, "need to send DRAG_STARTED to new window " + newWin);
@@ -293,6 +317,15 @@
         }
     }
 
+    private boolean isWindowNotified(WindowState newWin) {
+        for (WindowState ws : mNotifiedWindows) {
+            if (ws == newWin) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void broadcastDragEndedLw() {
         final int myPid = Process.myPid();
 
@@ -346,7 +379,9 @@
 
     private void cleanUpDragLw() {
         broadcastDragEndedLw();
-        restorePointerIconLw();
+        if (isFromSource(InputDevice.SOURCE_MOUSE)) {
+            mService.restorePointerIconLocked(mDisplayContent, mCurrentX, mCurrentY);
+        }
 
         // stop intercepting input
         unregister();
@@ -384,19 +419,18 @@
 
     void notifyLocationLw(float x, float y) {
         // Tell the affected window
-        WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+        WindowState touchedWin = mDisplayContent.getTouchableWinAtPointLocked(x, y);
         if (touchedWin == null) {
             if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y);
             return;
         }
-        if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
-            final IBinder touchedBinder = touchedWin.mClient.asBinder();
-            if (touchedBinder != mLocalWin) {
-                // This drag is pinned only to the originating window, but the drag
-                // point is outside that window.  Pretend it's over empty space.
-                touchedWin = null;
-            }
+
+        if (!isWindowNotified(touchedWin)) {
+            // The drag point is over a window which was not notified about a drag start.
+            // Pretend it's over empty space.
+            touchedWin = null;
         }
+
         try {
             final int myPid = Process.myPid();
 
@@ -430,22 +464,19 @@
         mTargetWindow = touchedWin;
     }
 
-    WindowState getDropTargetWinLw(float x, float y) {
-        return getTouchedWinAtPointLw(x, y);
-    }
-
-    // Tell the drop target about the data.  Returns 'true' if we can immediately
+    // Find the drop target and tell it about the data.  Returns 'true' if we can immediately
     // dispatch the global drag-ended message, 'false' if we need to wait for a
     // result from the recipient.
-    boolean notifyDropLw(WindowState touchedWin, IDropPermissions dropPermissions,
-            float x, float y) {
+    boolean notifyDropLw(float x, float y) {
         if (mAnimation != null) {
             return false;
         }
         mCurrentX = x;
         mCurrentY = y;
 
-        if (touchedWin == null) {
+        WindowState touchedWin = mDisplayContent.getTouchableWinAtPointLocked(x, y);
+
+        if (!isWindowNotified(touchedWin)) {
             // "drop" outside a valid window -- no recipient to apply a
             // timeout to, and we can send the drag-ended message immediately.
             mDragResult = false;
@@ -455,6 +486,23 @@
         if (DEBUG_DRAG) {
             Slog.d(TAG_WM, "sending DROP to " + touchedWin);
         }
+
+        final int targetUserId = UserHandle.getUserId(touchedWin.getOwningUid());
+
+        DropPermissionsHandler dropPermissions = null;
+        if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
+                (mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
+            dropPermissions = new DropPermissionsHandler(
+                    mData,
+                    mUid,
+                    touchedWin.getOwningPackage(),
+                    mFlags & DRAG_FLAGS_URI_PERMISSIONS,
+                    mSourceUserId,
+                    targetUserId);
+        }
+        if (mSourceUserId != targetUserId){
+            mData.fixUris(mSourceUserId);
+        }
         final int myPid = Process.myPid();
         final IBinder token = touchedWin.mClient.asBinder();
         DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
@@ -478,77 +526,17 @@
         return false;
     }
 
-    // Find the visible, touch-deliverable window under the given point
-    private WindowState getTouchedWinAtPointLw(float xf, float yf) {
-        WindowState touchedWin = null;
-        final int x = (int) xf;
-        final int y = (int) yf;
-
-        final WindowList windows = mService.getWindowListLocked(mDisplay);
-        if (windows == null) {
-            return null;
-        }
-        final int N = windows.size();
-        for (int i = N - 1; i >= 0; i--) {
-            WindowState child = windows.get(i);
-            final int flags = child.mAttrs.flags;
-            if (!child.isVisibleLw()) {
-                // not visible == don't tell about drags
-                continue;
-            }
-            if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
-                // not touchable == don't tell about drags
-                continue;
-            }
-
-            child.getVisibleBounds(mTmpRect);
-            if (!mTmpRect.contains(x, y)) {
-                // outside of this window's activity stack == don't tell about drags
-                continue;
-            }
-
-            child.getTouchableRegion(mTmpRegion);
-
-            final int touchFlags = flags &
-                    (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
-            if (mTmpRegion.contains(x, y) || touchFlags == 0) {
-                // Found it
-                touchedWin = child;
-                break;
-            }
-        }
-
-        return touchedWin;
-    }
-
     private static DragEvent obtainDragEvent(WindowState win, int action,
             float x, float y, Object localState,
             ClipDescription description, ClipData data,
             IDropPermissions dropPermissions,
             boolean result) {
-        final float winX = translateToWindowX(win, x);
-        final float winY = translateToWindowY(win, y);
+        final float winX = win.translateToWindowX(x);
+        final float winY = win.translateToWindowY(y);
         return DragEvent.obtain(action, winX, winY, localState, description, data,
                 dropPermissions, result);
     }
 
-    private static float translateToWindowX(WindowState win, float x) {
-        float winX = x - win.mFrame.left;
-        if (win.mEnforceSizeCompat) {
-            winX *= win.mGlobalScale;
-        }
-        return winX;
-    }
-
-    private static float translateToWindowY(WindowState win, float y) {
-        float winY = y - win.mFrame.top;
-        if (win.mEnforceSizeCompat) {
-            winY *= win.mGlobalScale;
-        }
-        return winY;
-    }
-
     boolean stepAnimationLocked(long currentTimeMs) {
         if (mAnimation == null) {
             return false;
@@ -604,21 +592,4 @@
             InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_GRAB);
         }
     }
-
-    private void restorePointerIconLw() {
-        if (isFromSource(InputDevice.SOURCE_MOUSE)) {
-            WindowState touchWin = getTouchedWinAtPointLw(mCurrentX, mCurrentY);
-            if (touchWin != null) {
-                try {
-                    touchWin.mClient.updatePointerIcon(
-                            translateToWindowX(touchWin, mCurrentX),
-                            translateToWindowY(touchWin, mCurrentY));
-                    return;
-                } catch (RemoteException e) {
-                    Slog.w(TAG_WM, "unable to restore pointer icon");
-                }
-            }
-            InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT);
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index a8d974f..25de75a 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -528,6 +528,16 @@
         }
     }
 
+    @Override
+    public void updatePointerIcon(IWindow window) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mService.updatePointerIcon(window);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     void windowAddedLocked() {
         if (mSurfaceSession == null) {
             if (WindowManagerService.localLOGV) Slog.v(
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index a06d3fc..fe55e80 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -536,11 +536,24 @@
     }
 
     void setDragResizing(boolean dragResizing) {
-        mDragResizing = dragResizing;
+        if (mDragResizing != dragResizing) {
+            mDragResizing = dragResizing;
+            resetDragResizingChangeReported();
+        }
+    }
+
+    void resetDragResizingChangeReported() {
+        for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
+            final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
+            for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+                final WindowState win = windows.get(winNdx);
+                win.resetDragResizingChangeReported();
+            }
+        }
     }
 
     boolean isDragResizing() {
-        return mDragResizing;
+        return mDragResizing || (mStack != null && mStack.isDragResizing());
     }
 
     void updateDisplayInfo(final DisplayContent displayContent) {
@@ -584,7 +597,7 @@
             final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                 final WindowState win = windows.get(winNdx);
-                if (!resizingWindows.contains(win)) {
+                if (win.mHasSurface && !resizingWindows.contains(win)) {
                     if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
                     resizingWindows.add(win);
                 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 40ca1c5..8409058 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -38,6 +38,7 @@
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.WindowManager.DOCKED_BOTTOM;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -99,6 +100,9 @@
     boolean mDeferDetach;
     private boolean mUpdateBoundsAfterRotation = false;
 
+    // Whether the stack and all its tasks is currently being drag-resized
+    private boolean mDragResizing;
+
     TaskStack(WindowManagerService service, int stackId) {
         mService = service;
         mStackId = stackId;
@@ -894,7 +898,8 @@
     }
 
     boolean isVisibleLocked() {
-        final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded();
+        final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded()
+                && !mService.mAnimator.mKeyguardGoingAway;
         if (keyguardOn && !StackId.isAllowedOverLockscreen(mStackId)) {
             // The keyguard is showing and the stack shouldn't show on top of the keyguard.
             return false;
@@ -911,6 +916,20 @@
         return false;
     }
 
+    boolean isDragResizing() {
+        return mDragResizing;
+    }
+
+    private void setDragResizingLocked(boolean resizing) {
+        if (mDragResizing == resizing) {
+            return;
+        }
+        mDragResizing = resizing;
+        for (int i = mTasks.size() - 1; i >= 0 ; i--) {
+            mTasks.get(i).resetDragResizingChangeReported();
+        }
+    }
+
     @Override  // AnimatesBounds
     public boolean setSize(Rect bounds) {
         synchronized (mService.mWindowMap) {
@@ -926,15 +945,23 @@
     }
 
     @Override  // AnimatesBounds
-    public void finishBoundsAnimation() {
+    public void onAnimationStart() {
         synchronized (mService.mWindowMap) {
-            if (mTasks.isEmpty()) {
-                return;
-            }
-            final Task task = mTasks.get(mTasks.size() - 1);
-            if (task != null) {
-                task.setDragResizing(false);
-                mService.requestTraversal();
+            setDragResizingLocked(true);
+        }
+    }
+
+    @Override  // AnimatesBounds
+    public void onAnimationEnd() {
+        synchronized (mService.mWindowMap) {
+            setDragResizingLocked(false);
+            mService.requestTraversal();
+        }
+        if (mStackId == PINNED_STACK_ID) {
+            try {
+                mService.mActivityManager.notifyPinnedStackAnimationEnded();
+            } catch (RemoteException e) {
+                // I don't believe you...
             }
         }
     }
@@ -952,4 +979,4 @@
     public void getFullScreenBounds(Rect bounds) {
         getDisplayContent().getContentRect(bounds);
     }
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 8d2fb9b..f8a4d33 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -21,6 +21,7 @@
 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 android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
@@ -231,7 +232,10 @@
         // Only hide windows if the keyguard is active and not animating away.
         boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded()
                 && mForceHiding != KEYGUARD_ANIMATING_OUT;
-        return keyguardOn && !allowWhenLocked && (win.getDisplayId() == Display.DEFAULT_DISPLAY);
+        boolean hideDockDivider = win.mAttrs.type == TYPE_DOCK_DIVIDER
+                && win.getDisplayContent().getDockedStackLocked() == null;
+        return keyguardOn && !allowWhenLocked && (win.getDisplayId() == Display.DEFAULT_DISPLAY)
+                || hideDockDivider;
     }
 
     private void updateWindowsLocked(final int displayId) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ae6c89a..7169375 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -41,6 +41,7 @@
 import android.graphics.Region;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
+import android.hardware.input.InputManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -81,6 +82,7 @@
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
+import android.view.PointerIcon;
 import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IApplicationToken;
 import android.view.IDockedStackListener;
@@ -466,6 +468,7 @@
     final float[] mTmpFloats = new float[9];
     final Rect mTmpRect = new Rect();
     final Rect mTmpRect2 = new Rect();
+    final Region mTmpRegion = new Region();
 
     boolean mDisplayReady;
     boolean mSafeMode;
@@ -661,13 +664,6 @@
 
     private WindowContentFrameStats mTempWindowRenderStats;
 
-    private static final int DRAG_FLAGS_URI_ACCESS = View.DRAG_FLAG_GLOBAL_URI_READ |
-            View.DRAG_FLAG_GLOBAL_URI_WRITE;
-
-    private static final int DRAG_FLAGS_URI_PERMISSIONS = DRAG_FLAGS_URI_ACCESS |
-            View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION |
-            View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;
-
     final class DragInputEventReceiver extends InputEventReceiver {
         // Set, if stylus button was down at the start of the drag.
         private boolean mStylusButtonDownAtStart;
@@ -713,7 +709,7 @@
                             if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at "
                                     + newX + "," + newY);
                             synchronized (mWindowMap) {
-                                endDrag = completeDropLw(newX, newY);
+                                endDrag = mDragState.notifyDropLw(newX, newY);
                             }
                         } else {
                             synchronized (mWindowMap) {
@@ -727,7 +723,7 @@
                         if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at "
                                 + newX + "," + newY);
                         synchronized (mWindowMap) {
-                            endDrag = completeDropLw(newX, newY);
+                            endDrag = mDragState.notifyDropLw(newX, newY);
                         }
                     } break;
 
@@ -757,25 +753,6 @@
         }
     }
 
-    private boolean completeDropLw(float x, float y) {
-        WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y);
-
-        DropPermissionsHandler dropPermissions = null;
-        if (dropTargetWin != null &&
-                (mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
-                (mDragState.mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
-            dropPermissions = new DropPermissionsHandler(
-                    mDragState.mData,
-                    mDragState.mUid,
-                    dropTargetWin.getOwningPackage(),
-                    mDragState.mFlags & DRAG_FLAGS_URI_PERMISSIONS,
-                    UserHandle.getUserId(mDragState.mUid),
-                    UserHandle.getUserId(dropTargetWin.getOwningUid()));
-        }
-
-        return mDragState.notifyDropLw(dropTargetWin, dropPermissions, x, y);
-    }
-
     /**
      * Whether the UI is currently running in touch mode (not showing
      * navigational focus because the user is directly pressing the screen).
@@ -1192,7 +1169,7 @@
                 break;
             }
         }
-        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
                         + windows.size());
         windows.add(i + 1, win);
@@ -1224,7 +1201,7 @@
                 //apptoken note that the window could be a floating window
                 //that was created later or a window at the top of the list of
                 //windows associated with this token.
-                if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+                if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                         "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
                                 + windows.size());
                 windows.add(newIdx + 1, win);
@@ -1262,7 +1239,7 @@
             }
         }
         i++;
-        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
+        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
                 "Free window: Adding window " + win + " at " + i + " of " + windows.size());
         windows.add(i, win);
         mWindowsChanged = true;
@@ -1333,7 +1310,7 @@
     }
 
     private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
-        if (DEBUG_FOCUS_LIGHT) Slog.d(TAG_WM, "addWindowToListInOrderLocked: win=" + win +
+        if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindowToListInOrderLocked: win=" + win +
                 " Callers=" + Debug.getCallers(4));
         if (win.mAttachedWindow == null) {
             final WindowToken token = win.mToken;
@@ -2154,6 +2131,14 @@
             if (win == null) {
                 return;
             }
+            // We set this here instead of removeWindowLocked because we only want it to be
+            // true when the client has requested we remove the window. In other remove
+            // cases, we have to wait for activity stop to safely remove the window (as the
+            // client may still be using the surface). In this case though, the client has
+            // just dismissed a window (for example a Dialog) and activity stop isn't
+            // necessarily imminent, so we need to know not to wait for it after our
+            // hanimation (if applicable) finishes.
+            win.mClientRemoveRequested = true;
             removeWindowLocked(win);
         }
     }
@@ -4188,6 +4173,24 @@
     }
 
     @Override
+    public void notifyAppStopped(IBinder token) {
+        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
+                "notifyAppStopped()")) {
+            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
+        }
+
+        synchronized(mWindowMap) {
+            final AppWindowToken wtoken;
+            wtoken = findAppWindowToken(token);
+            if (wtoken == null) {
+                Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
+                return;
+            }
+            wtoken.notifyAppStopped();
+        }
+    }
+
+    @Override
     public void setAppVisibility(IBinder token, boolean visible) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppVisibility()")) {
@@ -4219,6 +4222,8 @@
                 // if made visible again.
                 wtoken.appDied = false;
                 wtoken.removeAllWindows();
+            } else if (visible) {
+                wtoken.mAppStopped = false;
             }
 
             // If we are preparing an app transition, then delay changing
@@ -4836,6 +4841,7 @@
         }
     }
 
+    @Override
     public void getStackBounds(int stackId, Rect bounds) {
         synchronized (mWindowMap) {
             final TaskStack stack = mStackIdToStack.get(stackId);
@@ -8807,7 +8813,8 @@
                 Slog.v(TAG_WM, "Win " + w + " config changed: "
                         + mCurConfiguration);
             }
-            final boolean dragResizingChanged = w.isDragResizeChanged();
+            final boolean dragResizingChanged = w.isDragResizeChanged()
+                    && !w.isDragResizingChangeReported();
             if (localLOGV) Slog.v(TAG_WM, "Resizing " + w
                     + ": configChanged=" + configChanged
                     + " dragResizingChanged=" + dragResizingChanged
@@ -9592,6 +9599,11 @@
                 && !appWindow.mTask.inFreeformWorkspace();
     }
 
+    @Override
+    public int getDockedDividerInsetsLw() {
+        return getDefaultDisplayContentLocked().getDockedDividerController().getContentInsets();
+    }
+
     void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
         mPolicy.dump("    ", pw, args);
@@ -10136,6 +10148,7 @@
         if (displayId == Display.DEFAULT_DISPLAY) {
             displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
             registerPointerEventListener(displayContent.mTapDetector);
+            registerPointerEventListener(mMousePositionTracker);
         }
 
         return displayContent;
@@ -10228,6 +10241,7 @@
             displayContent.close();
             if (displayId == Display.DEFAULT_DISPLAY) {
                 unregisterPointerEventListener(displayContent.mTapDetector);
+                unregisterPointerEventListener(mMousePositionTracker);
             }
         }
         mAnimator.removeDisplayLocked(displayId);
@@ -10350,13 +10364,6 @@
                 Slog.w(TAG, "animateResizePinnedStack: stackId " + PINNED_STACK_ID + " not found.");
                 return;
             }
-            final ArrayList<Task> tasks = stack.getTasks();
-            if (tasks.isEmpty()) {
-                Slog.w(TAG, "animateResizePinnedStack: pinned stack doesn't have any tasks.");
-                return;
-            }
-            final Task task = tasks.get(tasks.size() - 1);
-            task.setDragResizing(true);
             final Rect originalBounds = new Rect();
             stack.getBounds(originalBounds);
             UiThread.getHandler().post(new Runnable() {
@@ -10434,6 +10441,92 @@
         }
     }
 
+    private MousePositionTracker mMousePositionTracker = new MousePositionTracker();
+
+    private static class MousePositionTracker implements PointerEventListener {
+        private boolean mLatestEventWasMouse;
+        private float mLatestMouseX;
+        private float mLatestMouseY;
+
+        void updatePosition(float x, float y) {
+            synchronized (this) {
+                mLatestEventWasMouse = true;
+                mLatestMouseX = x;
+                mLatestMouseY = y;
+            }
+        }
+
+        @Override
+        public void onPointerEvent(MotionEvent motionEvent) {
+            if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) {
+                updatePosition(motionEvent.getRawX(), motionEvent.getRawY());
+            } else {
+                synchronized (this) {
+                    mLatestEventWasMouse = false;
+                }
+            }
+        }
+    };
+
+    void updatePointerIcon(IWindow client) {
+        float mouseX, mouseY;
+
+        synchronized(mMousePositionTracker) {
+            if (!mMousePositionTracker.mLatestEventWasMouse) {
+                return;
+            }
+            mouseX = mMousePositionTracker.mLatestMouseX;
+            mouseY = mMousePositionTracker.mLatestMouseY;
+        }
+
+        synchronized (mWindowMap) {
+            if (mDragState != null) {
+                // Drag cursor overrides the app cursor.
+                return;
+            }
+            WindowState callingWin = windowForClientLocked(null, client, false);
+            if (callingWin == null) {
+                Slog.w(TAG_WM, "Bad requesting window " + client);
+                return;
+            }
+            final DisplayContent displayContent = callingWin.getDisplayContent();
+            if (displayContent == null) {
+                return;
+            }
+            WindowState windowUnderPointer =
+                    displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
+            if (windowUnderPointer != callingWin) {
+                return;
+            }
+            try {
+                windowUnderPointer.mClient.updatePointerIcon(
+                        windowUnderPointer.translateToWindowX(mouseX),
+                        windowUnderPointer.translateToWindowY(mouseY));
+            } catch (RemoteException e) {
+                Slog.w(TAG_WM, "unable to update pointer icon");
+            }
+        }
+    }
+
+    void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
+        // Mouse position tracker has not been getting updates while dragging, update it now.
+        mMousePositionTracker.updatePosition(latestX, latestY);
+
+        WindowState windowUnderPointer =
+                displayContent.getTouchableWinAtPointLocked(latestX, latestY);
+        if (windowUnderPointer != null) {
+            try {
+                windowUnderPointer.mClient.updatePointerIcon(
+                        windowUnderPointer.translateToWindowX(latestX),
+                        windowUnderPointer.translateToWindowY(latestY));
+            } catch (RemoteException e) {
+                Slog.w(TAG_WM, "unable to restore pointer icon");
+            }
+        } else {
+            InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT);
+        }
+    }
+
     private final class LocalService extends WindowManagerInternal {
         @Override
         public void requestTraversalFromDisplayManager() {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 880514c..bea333b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -161,6 +161,7 @@
     boolean mAttachedHidden;    // is our parent window hidden?
     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
     boolean mDragResizing;
+    boolean mDragResizingChangeReported;
     int mResizeMode;
 
     RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
@@ -386,6 +387,13 @@
     boolean mRemoved;
 
     /**
+     * Has the client requested we remove the window? In this case we know
+     * that we can dispose of it when we wish without further synchronization
+     * with the client
+     */
+    boolean mClientRemoveRequested;
+
+    /**
      * Temp for keeping track of windows that have been removed when
      * rebuilding window list.
      */
@@ -1614,11 +1622,14 @@
                         mService.removeWindowLocked(win);
                         if (win.mAttrs.type == TYPE_DOCK_DIVIDER) {
                             // The owner of the docked divider died :( We reset the docked stack,
-                            // just in case they have the divider at an unstable position.
+                            // just in case they have the divider at an unstable position. Better
+                            // also reset drag resizing state, because the owner can't do it
+                            // anymore.
                             final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
                             if (stack != null) {
                                 stack.resetDockedStackToMiddle();
                             }
+                            mService.setDockedStackResizing(false);
                         }
                     } else if (mHasSurface) {
                         Slog.e(TAG, "!!! LEAK !!! Window removed but surface still valid.");
@@ -2078,7 +2089,8 @@
         return mTmpRect;
     }
 
-    private int getStackId() {
+    @Override
+    public int getStackId() {
         final TaskStack stack = getStack();
         if (stack == null) {
             return INVALID_STACK_ID;
@@ -2092,6 +2104,7 @@
         mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets,
                 reportDraw, newConfig, getBackdropFrame(frame),
                 isDragResizeChanged() /* forceRelayout */);
+        mDragResizingChangeReported = true;
     }
 
     public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -2126,6 +2139,20 @@
         return mDragResizing != computeDragResizing();
     }
 
+    /**
+     * @return Whether we reported a drag resize change to the application or not already.
+     */
+    boolean isDragResizingChangeReported() {
+        return mDragResizingChangeReported;
+    }
+
+    /**
+     * Resets the state whether we reported a drag resize change to the app.
+     */
+    void resetDragResizingChangeReported() {
+        mDragResizingChangeReported = false;
+    }
+
     int getResizeMode() {
         return mResizeMode;
     }
@@ -2145,12 +2172,16 @@
         // background.
         return (mDisplayContent.mDividerControllerLocked.isResizing()
                         || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) &&
-                !task.inFreeformWorkspace();
+                !task.inFreeformWorkspace() && isVisibleLw();
 
     }
 
     void setDragResizing() {
-        mDragResizing = computeDragResizing();
+        final boolean resizing = computeDragResizing();
+        if (resizing == mDragResizing) {
+            return;
+        }
+        mDragResizing = resizing;
         mResizeMode = mDragResizing && mDisplayContent.mDividerControllerLocked.isResizing()
                 ? DRAG_RESIZE_MODE_DOCKED_DIVIDER
                 : DRAG_RESIZE_MODE_FREEFORM;
@@ -2472,4 +2503,20 @@
         mReplacingWindow = null;
         mAnimateReplacingWindow = false;
     }
+
+    float translateToWindowX(float x) {
+        float winX = x - mFrame.left;
+        if (mEnforceSizeCompat) {
+            winX *= mGlobalScale;
+        }
+        return winX;
+    }
+
+    float translateToWindowY(float y) {
+        float winY = y - mFrame.top;
+        if (mEnforceSizeCompat) {
+            winY *= mGlobalScale;
+        }
+        return winY;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index c7c9cbf..0201296 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -471,16 +471,31 @@
         if (WindowManagerService.localLOGV) Slog.v(
                 TAG, "Exit animation finished in " + this
                 + ": remove=" + mWin.mRemoveOnExit);
-        if (hasSurface()) {
-            mService.mDestroySurface.add(mWin);
-            mWin.mDestroying = true;
-            hide("finishExit");
+
+
+        mWin.mDestroying = true;
+
+        // If we have an app token, we ask it to destroy the surface for us,
+        // so that it can take care to ensure the activity has actually stopped
+        // and the surface is not still in use. Otherwise we add the service to
+        // mDestroySurface and allow it to be processed in our next transaction.
+        if (mWin.mAppToken != null) {
+            if (hasSurface()) {
+                hide("finishExit");
+            }
+            mWin.mAppToken.destroySurfaces();
+        } else {
+            if (hasSurface()) {
+                mService.mDestroySurface.add(mWin);
+                hide("finishExit");
+            }
+            mWin.mExiting = false;
+            if (mWin.mRemoveOnExit) {
+                mService.mPendingRemove.add(mWin);
+                mWin.mRemoveOnExit = false;
+            }
         }
-        mWin.mExiting = false;
-        if (mWin.mRemoveOnExit) {
-            mService.mPendingRemove.add(mWin);
-            mWin.mRemoveOnExit = false;
-        }
+
         mWallpaperControllerLocked.hideWallpapers(mWin);
     }
 
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
index b72cf4d..656c214 100644
--- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
+++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
@@ -330,7 +330,7 @@
     jsize len = env->GetArrayLength(body);
     message.length = MIN(len, CEC_MESSAGE_BODY_MAX_LENGTH);
     ScopedByteArrayRO bodyPtr(env, body);
-    std::memcpy(message.body, bodyPtr.get(), len);
+    std::memcpy(message.body, bodyPtr.get(), message.length);
 
     HdmiCecController* controller =
             reinterpret_cast<HdmiCecController*>(controllerPtr);
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index e75775f..cdd5519 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -68,13 +68,14 @@
 static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
 static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL;
 
-#define MAX_SATELLITE_COUNT 512
-#define MAX_GPS_SATELLITE_COUNT 512
+#define GPS_MAX_SATELLITE_COUNT 32
+#define GNSS_MAX_SATELLITE_COUNT 64
 
-#define PRN_SHIFT_WIDTH 3
+#define SVID_SHIFT_WIDTH 7
+#define CONSTELLATION_TYPE_SHIFT_WIDTH 3
 
 // temporary storage for GPS callbacks
-static GnssSvInfo sGnssSvList[MAX_SATELLITE_COUNT];
+static GnssSvInfo sGnssSvList[GNSS_MAX_SATELLITE_COUNT];
 static size_t sGnssSvListSize;
 static const char* sNmeaString;
 static int sNmeaStringLength;
@@ -113,56 +114,75 @@
 {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     size_t status_size = sv_status->size;
-    // Some drive doesn't set the size field correctly. Assume GpsSvStatus_v1 if
-    // it doesn't provide a valid size.
+    // Some drives doesn't set the size field correctly. Assume GpsSvStatus_v1
+    // if it doesn't provide a valid size.
     if (status_size == 0) {
-        status_size = sizeof(GpsSvStatus_v1);
+        ALOGW("Invalid size of GpsSvStatus found: %zd.", status_size);
     }
-    if (status_size == sizeof(GpsSvStatus)) {
-        sGnssSvListSize = sv_status->gnss_sv_list_size;
-        // Cramp the list size
-        if (sGnssSvListSize > MAX_SATELLITE_COUNT) {
-            sGnssSvListSize = MAX_SATELLITE_COUNT;
-        }
-        // Copy GNSS SV info into sGnssSvList, if any.
-        if (sGnssSvListSize > 0 && sv_status->gnss_sv_list) {
-            memcpy(sGnssSvList, sv_status->gnss_sv_list, sizeof(GnssSvInfo) * sGnssSvListSize);
-        }
-    } else if (status_size == sizeof(GpsSvStatus_v1)) {
-        sGnssSvListSize = sv_status->num_svs;
-        // Cramp the list size
-        if (sGnssSvListSize > MAX_GPS_SATELLITE_COUNT) {
-            sGnssSvListSize = MAX_GPS_SATELLITE_COUNT;
-        }
-        uint32_t ephemeris_mask = sv_status->ephemeris_mask;
-        uint32_t almanac_mask = sv_status->almanac_mask;
-        uint32_t used_in_fix_mask = sv_status->used_in_fix_mask;
-        for (size_t i = 0; i < sGnssSvListSize; i++) {
-            GnssSvInfo& info = sGnssSvList[i];
+    sGnssSvListSize = sv_status->num_svs;
+    // Clamp the list size. Legacy GpsSvStatus has only 32 elements in sv_list.
+    if (sGnssSvListSize > GPS_MAX_SATELLITE_COUNT) {
+        ALOGW("Too many satellites %zd. Clamps to %d.",
+              sGnssSvListSize,
+              GPS_MAX_SATELLITE_COUNT);
+        sGnssSvListSize = GPS_MAX_SATELLITE_COUNT;
+    }
+    uint32_t ephemeris_mask = sv_status->ephemeris_mask;
+    uint32_t almanac_mask = sv_status->almanac_mask;
+    uint32_t used_in_fix_mask = sv_status->used_in_fix_mask;
+    for (size_t i = 0; i < sGnssSvListSize; i++) {
+        GnssSvInfo& info = sGnssSvList[i];
+        info.svid = sv_status->sv_list[i].prn;
+        // TODO: implement the correct logic to derive the constellation type
+        // based on PRN ranges.
+        if (info.svid >=1 && info.svid <= 32) {
             info.constellation = GNSS_CONSTELLATION_GPS;
-            info.prn = sv_status->sv_list[i].prn;
-            info.snr = sv_status->sv_list[i].snr;
-            info.elevation = sv_status->sv_list[i].elevation;
-            info.azimuth = sv_status->sv_list[i].azimuth;
-            info.flags = GNSS_SV_FLAGS_NONE;
-            if (info.prn > 0 && info.prn <= 32) {
-              int32_t this_prn_mask = (1 << (info.prn - 1));
-              if ((ephemeris_mask & this_prn_mask) != 0) {
+        } else {
+            info.constellation = GNSS_CONSTELLATION_UNKNOWN;
+        }
+        info.snr = sv_status->sv_list[i].snr;
+        info.elevation = sv_status->sv_list[i].elevation;
+        info.azimuth = sv_status->sv_list[i].azimuth;
+        info.flags = GNSS_SV_FLAGS_NONE;
+        if (info.svid > 0 && info.svid <= 32) {
+            int32_t this_svid_mask = (1 << (info.svid - 1));
+            if ((ephemeris_mask & this_svid_mask) != 0) {
                 info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA;
-              }
-              if ((almanac_mask & this_prn_mask) != 0) {
+            }
+            if ((almanac_mask & this_svid_mask) != 0) {
                 info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA;
-              }
-              if ((used_in_fix_mask & this_prn_mask) != 0) {
+            }
+            if ((used_in_fix_mask & this_svid_mask) != 0) {
                 info.flags |= GNSS_SV_FLAGS_USED_IN_FIX;
-              }
             }
         }
-    } else {
-        sGnssSvListSize = 0;
-        ALOGE("Invalid size of GpsSvStatus found: %zd.", status_size);
+    }
+    env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+}
+
+static void gnss_sv_status_callback(GnssSvStatus* sv_status) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    size_t status_size = sv_status->size;
+    // Check the size, and reject the object that has invalid size.
+    if (status_size != sizeof(GnssSvStatus)) {
+        ALOGE("Invalid size of GnssSvStatus found: %zd.", status_size);
         return;
     }
+    sGnssSvListSize = sv_status->num_svs;
+    // Clamp the list size
+    if (sGnssSvListSize > GNSS_MAX_SATELLITE_COUNT) {
+        ALOGD("Too many satellites %zd. Clamps to %d.",
+              sGnssSvListSize,
+              GNSS_MAX_SATELLITE_COUNT);
+        sGnssSvListSize = GNSS_MAX_SATELLITE_COUNT;
+    }
+    // Copy GNSS SV info into sGnssSvList, if any.
+    if (sGnssSvListSize > 0) {
+        memcpy(sGnssSvList,
+               sv_status->gnss_sv_list,
+               sizeof(GnssSvInfo) * sGnssSvListSize);
+    }
     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 }
@@ -228,6 +248,7 @@
     create_thread_callback,
     request_utc_time_callback,
     set_system_info_callback,
+    gnss_sv_status_callback,
 };
 
 static void xtra_download_request_callback()
@@ -677,31 +698,30 @@
 }
 
 static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
-        jintArray prnWithFlagArray, jfloatArray snrArray, jfloatArray elevArray,
-        jfloatArray azumArray, jintArray constellationTypeArray)
+        jintArray svidWithFlagArray, jfloatArray snrArray, jfloatArray elevArray,
+        jfloatArray azumArray)
 {
     // this should only be called from within a call to reportSvStatus
-    jint* prnWithFlags = env->GetIntArrayElements(prnWithFlagArray, 0);
+    jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
     jfloat* snrs = env->GetFloatArrayElements(snrArray, 0);
     jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
     jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
-    jint* constellationTypes = env->GetIntArrayElements(constellationTypeArray, 0);
 
     // GNSS SV info.
     for (size_t i = 0; i < sGnssSvListSize; ++i) {
         const GnssSvInfo& info = sGnssSvList[i];
-        constellationTypes[i] = info.constellation;
-        prnWithFlags[i] = (info.prn << PRN_SHIFT_WIDTH) | info.flags;
+        svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
+            (info.constellation << CONSTELLATION_TYPE_SHIFT_WIDTH) |
+            info.flags;
         snrs[i] = info.snr;
         elev[i] = info.elevation;
         azim[i] = info.azimuth;
     }
 
-    env->ReleaseIntArrayElements(prnWithFlagArray, prnWithFlags, 0);
+    env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
     env->ReleaseFloatArrayElements(snrArray, snrs, 0);
     env->ReleaseFloatArrayElements(elevArray, elev, 0);
     env->ReleaseFloatArrayElements(azumArray, azim, 0);
-    env->ReleaseIntArrayElements(constellationTypeArray, constellationTypes, 0);
     return (jint) sGnssSvListSize;
 }
 
@@ -968,370 +988,341 @@
     return JNI_FALSE;
 }
 
-static jobject translate_gps_clock(JNIEnv* env, void* data, size_t size) {
-    const char* doubleSignature = "(D)V";
-    const char* longSignature = "(J)V";
+template<class T>
+class JavaMethodHelper {
+  public:
+   // Helper function to call setter on a Java object.
+   static void callJavaMethod(
+           JNIEnv* env,
+           jclass clazz,
+           jobject object,
+           const char* method_name,
+           T value);
 
-    GpsClock* clock = reinterpret_cast<GpsClock*>(data);
+  private:
+    static const char *const signature_;
+};
 
-    jclass gpsClockClass = env->FindClass("android/location/GnssClock");
-    jmethodID gpsClockCtor = env->GetMethodID(gpsClockClass, "<init>", "()V");
+template<class T>
+void JavaMethodHelper<T>::callJavaMethod(
+        JNIEnv* env,
+        jclass clazz,
+        jobject object,
+        const char* method_name,
+        T value) {
+    jmethodID method = env->GetMethodID(clazz, method_name, signature_);
+    env->CallVoidMethod(object, method, value);
+}
 
-    jobject gpsClockObject = env->NewObject(gpsClockClass, gpsClockCtor);
+class JavaObject {
+  public:
+   JavaObject(JNIEnv* env, const char* class_name);
+   virtual ~JavaObject();
+
+   template<class T>
+   void callSetter(const char* method_name, T value);
+   template<class T>
+   void callSetter(const char* method_name, T* value, size_t size);
+   jobject get();
+
+  private:
+   JNIEnv* env_;
+   jclass clazz_;
+   jobject object_;
+};
+
+JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
+    clazz_ = env_->FindClass(class_name);
+    jmethodID ctor = env->GetMethodID(clazz_, "<init>", "()V");
+    object_ = env_->NewObject(clazz_, ctor);
+}
+
+JavaObject::~JavaObject() {
+    env_->DeleteLocalRef(clazz_);
+}
+
+template<class T>
+void JavaObject::callSetter(const char* method_name, T value) {
+    JavaMethodHelper<T>::callJavaMethod(
+            env_, clazz_, object_, method_name, value);
+}
+
+template<>
+void JavaObject::callSetter(
+        const char* method_name, uint8_t* value, size_t size) {
+    jbyteArray array = env_->NewByteArray(size);
+    env_->SetByteArrayRegion(array, 0, size, (jbyte*) value);
+    jmethodID method = env_->GetMethodID(
+            clazz_,
+            method_name,
+            "([B)V");
+    env_->CallVoidMethod(object_, method, array);
+}
+
+jobject JavaObject::get() {
+    return object_;
+}
+
+// Define Java method signatures for all known types.
+
+template<>
+const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
+template<>
+const char *const JavaMethodHelper<int8_t>::signature_ = "(B)V";
+template<>
+const char *const JavaMethodHelper<int16_t>::signature_ = "(S)V";
+template<>
+const char *const JavaMethodHelper<uint16_t>::signature_ = "(S)V";
+template<>
+const char *const JavaMethodHelper<int>::signature_ = "(I)V";
+template<>
+const char *const JavaMethodHelper<int64_t>::signature_ = "(J)V";
+template<>
+const char *const JavaMethodHelper<float>::signature_ = "(F)V";
+template<>
+const char *const JavaMethodHelper<double>::signature_ = "(D)V";
+template<>
+const char *const JavaMethodHelper<bool>::signature_ = "(Z)V";
+
+#define SET(setter, value) object.callSetter("set" # setter, (value))
+#define SET_IF(flag, setter, value) \
+        if (flags & (flag)) object.callSetter("set" # setter, (value))
+
+static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) {
+    JavaObject object(env, "android/location/GnssClock");
     GpsClockFlags flags = clock->flags;
 
-    if (flags & GPS_CLOCK_HAS_LEAP_SECOND) {
-        jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setLeapSecond", "(S)V");
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->leap_second);
-   }
+    SET_IF(GPS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
+    SET(Type, clock->type);
+    SET(TimeInNs, clock->time_ns);
+    SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
+           TimeUncertaintyInNs,
+           clock->time_uncertainty_ns);
+    SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
+    SET_IF(GPS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+    SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
+           BiasUncertaintyInNs,
+           clock->bias_uncertainty_ns);
+    SET_IF(GPS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+    SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
+           DriftUncertaintyInNsPerSec,
+           clock->drift_uncertainty_nsps);
 
-   jmethodID typeSetterMethod = env->GetMethodID(gpsClockClass, "setType", "(B)V");
-   env->CallVoidMethod(gpsClockObject, typeSetterMethod, clock->type);
-
-    jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setTimeInNs", longSignature);
-    env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_ns);
-
-    if (flags & GPS_CLOCK_HAS_TIME_UNCERTAINTY) {
-        jmethodID setterMethod =
-                env->GetMethodID(gpsClockClass, "setTimeUncertaintyInNs", doubleSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->time_uncertainty_ns);
-    }
-
-    if (flags & GPS_CLOCK_HAS_FULL_BIAS) {
-        jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setFullBiasInNs", longSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->full_bias_ns);
-    }
-
-    if (flags & GPS_CLOCK_HAS_BIAS) {
-        jmethodID setterMethod = env->GetMethodID(gpsClockClass, "setBiasInNs", doubleSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_ns);
-    }
-
-    if (flags & GPS_CLOCK_HAS_BIAS_UNCERTAINTY) {
-        jmethodID setterMethod =
-                env->GetMethodID(gpsClockClass, "setBiasUncertaintyInNs", doubleSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->bias_uncertainty_ns);
-    }
-
-    if (flags & GPS_CLOCK_HAS_DRIFT) {
-        jmethodID setterMethod =
-                env->GetMethodID(gpsClockClass, "setDriftInNsPerSec", doubleSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_nsps);
-    }
-
-    if (flags & GPS_CLOCK_HAS_DRIFT_UNCERTAINTY) {
-        jmethodID setterMethod =
-                env->GetMethodID(gpsClockClass, "setDriftUncertaintyInNsPerSec", doubleSignature);
-        env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps);
-    }
-
+    /*
     if (flags & GPS_CLOCK_TYPE_LOCAL_HW_TIME) {
-        if (size == sizeof(GpsClock)) {
+        if (size == sizeof(GnssClock)) {
             jmethodID setterMethod =
                     env->GetMethodID(gpsClockClass,
                                      "setTimeOfLastHwClockDiscontinuityInNs",
                                      longSignature);
             env->CallVoidMethod(gpsClockObject,
                                 setterMethod,
-                                clock->time_of_last_hw_clock_discontinuity_ns);
+                                reinterpret_cast<GnssClock*>(clock)->time_of_last_hw_clock_discontinuity_ns);
         }
     }
+    */
 
-    env->DeleteLocalRef(gpsClockClass);
-    return gpsClockObject;
+    return object.get();
 }
 
-static jobject translate_gps_measurement(JNIEnv* env, void* data, size_t size) {
-    const char* byteSignature = "(B)V";
-    const char* shortSignature = "(S)V";
-    const char* intSignature = "(I)V";
-    const char* longSignature = "(J)V";
-    const char* floatSignature = "(F)V";
-    const char* doubleSignature = "(D)V";
+static jobject translate_gnss_clock(JNIEnv* env, GnssClock* clock) {
+    JavaObject object(env, "android/location/GnssClock");
+    GpsClockFlags flags = clock->flags;
 
-    jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
-    jmethodID gnssMeasurementCtor = env->GetMethodID(gnssMeasurementClass, "<init>", "()V");
-    GpsMeasurement* measurement = reinterpret_cast<GpsMeasurement*>(data);
+    SET_IF(GPS_CLOCK_HAS_LEAP_SECOND, LeapSecond, clock->leap_second);
+    SET(Type, clock->type);
+    SET(TimeInNs, clock->time_ns);
+    SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
+           TimeUncertaintyInNs,
+           clock->time_uncertainty_ns);
+    SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasInNs, clock->full_bias_ns);
+    SET_IF(GPS_CLOCK_HAS_BIAS, BiasInNs, clock->bias_ns);
+    SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
+           BiasUncertaintyInNs,
+           clock->bias_uncertainty_ns);
+    SET_IF(GPS_CLOCK_HAS_DRIFT, DriftInNsPerSec, clock->drift_nsps);
+    SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
+           DriftUncertaintyInNsPerSec,
+           clock->drift_uncertainty_nsps);
 
-    jobject gnssMeasurementObject = env->NewObject(gnssMeasurementClass, gnssMeasurementCtor);
+    SET_IF(GPS_CLOCK_TYPE_LOCAL_HW_TIME,
+           TimeOfLastHwClockDiscontinuityInNs,
+           clock->time_of_last_hw_clock_discontinuity_ns);
+
+    return object.get();
+}
+
+static jobject translate_gps_measurement(JNIEnv* env,
+                                         GpsMeasurement* measurement) {
+    JavaObject object(env, "android/location/GnssMeasurement");
     GpsMeasurementFlags flags = measurement->flags;
 
-    jmethodID prnSetterMethod = env->GetMethodID(gnssMeasurementClass, "setPrn", byteSignature);
-    env->CallVoidMethod(gnssMeasurementObject, prnSetterMethod, measurement->prn);
+    SET(Svid, static_cast<int16_t>(measurement->prn));
+    SET(TimeOffsetInNs, measurement->time_offset_ns);
+    SET(State, measurement->state);
+    SET(ReceivedGpsTowInNs, measurement->received_gps_tow_ns);
+    SET(ReceivedGpsTowUncertaintyInNs,
+        measurement->received_gps_tow_uncertainty_ns);
+    SET(Cn0InDbHz, measurement->c_n0_dbhz);
+    SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
+    SET(PseudorangeRateUncertaintyInMetersPerSec,
+        measurement->pseudorange_rate_uncertainty_mps);
+    SET(AccumulatedDeltaRangeState, measurement->accumulated_delta_range_state);
+    SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
+    SET(AccumulatedDeltaRangeUncertaintyInMeters,
+        measurement->accumulated_delta_range_uncertainty_m);
+    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE,
+           PseudorangeInMeters,
+           measurement->pseudorange_m);
+    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
+           PseudorangeUncertaintyInMeters,
+           measurement->pseudorange_uncertainty_m);
+    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE,
+           CodePhaseInChips,
+           measurement->code_phase_chips);
+    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
+           CodePhaseUncertaintyInChips,
+           measurement->code_phase_uncertainty_chips);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
+           CarrierFrequencyInHz,
+           measurement->carrier_frequency_hz);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_CYCLES,
+           CarrierCycles,
+           measurement->carrier_cycles);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE,
+           CarrierPhase,
+           measurement->carrier_phase);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
+           CarrierPhaseUncertainty,
+           measurement->carrier_phase_uncertainty);
+    SET(LossOfLock, measurement->loss_of_lock);
+    SET_IF(GPS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
+    SET_IF(GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
+           TimeFromLastBitInMs,
+           measurement->time_from_last_bit_ms);
+    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT,
+           DopplerShiftInHz,
+           measurement->doppler_shift_hz);
+    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
+           DopplerShiftUncertaintyInHz,
+           measurement->doppler_shift_uncertainty_hz);
+    SET(MultipathIndicator, measurement->multipath_indicator);
+    SET_IF(GPS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
+    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION,
+           ElevationInDeg,
+           measurement->elevation_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
+           ElevationUncertaintyInDeg,
+           measurement->elevation_uncertainty_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH,
+           AzimuthInDeg,
+           measurement->azimuth_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
+           AzimuthUncertaintyInDeg,
+           measurement->azimuth_uncertainty_deg);
+    SET(UsedInFix,
+        (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
 
-    jmethodID timeOffsetSetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setTimeOffsetInNs", doubleSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            timeOffsetSetterMethod,
-            measurement->time_offset_ns);
-
-    jmethodID stateSetterMethod = env->GetMethodID(gnssMeasurementClass, "setState", shortSignature);
-    env->CallVoidMethod(gnssMeasurementObject, stateSetterMethod, measurement->state);
-
-    jmethodID receivedGpsTowSetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setReceivedGpsTowInNs", longSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            receivedGpsTowSetterMethod,
-            measurement->received_gps_tow_ns);
-
-    jmethodID receivedGpsTowUncertaintySetterMethod = env->GetMethodID(
-            gnssMeasurementClass,
-            "setReceivedGpsTowUncertaintyInNs",
-            longSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            receivedGpsTowUncertaintySetterMethod,
-            measurement->received_gps_tow_uncertainty_ns);
-
-    jmethodID cn0SetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setCn0InDbHz", doubleSignature);
-    env->CallVoidMethod(gnssMeasurementObject, cn0SetterMethod, measurement->c_n0_dbhz);
-
-    jmethodID pseudorangeRateSetterMethod = env->GetMethodID(
-            gnssMeasurementClass,
-            "setPseudorangeRateInMetersPerSec",
-            doubleSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            pseudorangeRateSetterMethod,
-            measurement->pseudorange_rate_mps);
-
-    jmethodID pseudorangeRateUncertaintySetterMethod = env->GetMethodID(
-            gnssMeasurementClass,
-            "setPseudorangeRateUncertaintyInMetersPerSec",
-            doubleSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            pseudorangeRateUncertaintySetterMethod,
-            measurement->pseudorange_rate_uncertainty_mps);
-
-    jmethodID accumulatedDeltaRangeStateSetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setAccumulatedDeltaRangeState", shortSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            accumulatedDeltaRangeStateSetterMethod,
-            measurement->accumulated_delta_range_state);
-
-    jmethodID accumulatedDeltaRangeSetterMethod = env->GetMethodID(
-            gnssMeasurementClass,
-            "setAccumulatedDeltaRangeInMeters",
-            doubleSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            accumulatedDeltaRangeSetterMethod,
-            measurement->accumulated_delta_range_m);
-
-    jmethodID accumulatedDeltaRangeUncertaintySetterMethod = env->GetMethodID(
-            gnssMeasurementClass,
-            "setAccumulatedDeltaRangeUncertaintyInMeters",
-            doubleSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            accumulatedDeltaRangeUncertaintySetterMethod,
-            measurement->accumulated_delta_range_uncertainty_m);
-
-    if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setPseudorangeInMeters", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->pseudorange_m);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY) {
-        jmethodID setterMethod = env->GetMethodID(
-                gnssMeasurementClass,
-                "setPseudorangeUncertaintyInMeters",
-                doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->pseudorange_uncertainty_m);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setCodePhaseInChips", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->code_phase_chips);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY) {
-        jmethodID setterMethod = env->GetMethodID(
-                gnssMeasurementClass,
-                "setCodePhaseUncertaintyInChips",
-                doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->code_phase_uncertainty_chips);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setCarrierFrequencyInHz", floatSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->carrier_frequency_hz);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CARRIER_CYCLES) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setCarrierCycles", longSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->carrier_cycles);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setCarrierPhase", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->carrier_phase);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY) {
-        jmethodID setterMethod = env->GetMethodID(
-                gnssMeasurementClass,
-                "setCarrierPhaseUncertainty",
-                doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->carrier_phase_uncertainty);
-    }
-
-    jmethodID lossOfLockSetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setLossOfLock", byteSignature);
-    env->CallVoidMethod(gnssMeasurementObject, lossOfLockSetterMethod, measurement->loss_of_lock);
-
-    if (flags & GPS_MEASUREMENT_HAS_BIT_NUMBER) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setBitNumber", intSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->bit_number);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setTimeFromLastBitInMs", shortSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->time_from_last_bit_ms);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setDopplerShiftInHz", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->doppler_shift_hz);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY) {
-        jmethodID setterMethod = env->GetMethodID(
-                gnssMeasurementClass,
-                "setDopplerShiftUncertaintyInHz",
-                doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->doppler_shift_uncertainty_hz);
-    }
-
-    jmethodID multipathIndicatorSetterMethod =
-            env->GetMethodID(gnssMeasurementClass, "setMultipathIndicator", byteSignature);
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            multipathIndicatorSetterMethod,
-            measurement->multipath_indicator);
-
-    if (flags & GPS_MEASUREMENT_HAS_SNR) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setSnrInDb", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->snr_db);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_ELEVATION) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setElevationInDeg", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->elevation_deg);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setElevationUncertaintyInDeg", doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->elevation_uncertainty_deg);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_AZIMUTH) {
-        jmethodID setterMethod =
-                env->GetMethodID(gnssMeasurementClass, "setAzimuthInDeg", doubleSignature);
-        env->CallVoidMethod(gnssMeasurementObject, setterMethod, measurement->azimuth_deg);
-    }
-
-    if (flags & GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY) {
-        jmethodID setterMethod = env->GetMethodID(
-                gnssMeasurementClass,
-                "setAzimuthUncertaintyInDeg",
-                doubleSignature);
-        env->CallVoidMethod(
-                gnssMeasurementObject,
-                setterMethod,
-                measurement->azimuth_uncertainty_deg);
-    }
-
-    jmethodID usedInFixSetterMethod = env->GetMethodID(gnssMeasurementClass, "setUsedInFix", "(Z)V");
-    env->CallVoidMethod(
-            gnssMeasurementObject,
-            usedInFixSetterMethod,
-            (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
-
-    if (size == sizeof(GpsMeasurement)) {
-      jmethodID setterMethod =
-          env->GetMethodID(gnssMeasurementClass,
-                           "setPseudorangeRateCarrierInMetersPerSec",
-                           doubleSignature);
-      env->CallVoidMethod(
-          gnssMeasurementObject,
-          setterMethod,
-          measurement->pseudorange_rate_carrier_mps);
-
-      setterMethod =
-          env->GetMethodID(gnssMeasurementClass,
-                           "setPseudorangeRateCarrierUncertaintyInMetersPerSec",
-                           doubleSignature);
-      env->CallVoidMethod(
-          gnssMeasurementObject,
-          setterMethod,
-          measurement->pseudorange_rate_carrier_uncertainty_mps);
-    }
-
-    env->DeleteLocalRef(gnssMeasurementClass);
-    return gnssMeasurementObject;
+    return object.get();
 }
 
-/**
- * <T> can only be GpsData or GpsData_v1. Must rewrite this function if more
- * types are introduced in the future releases.
- */
-template<class T>
-static jobjectArray translate_gps_measurements(JNIEnv* env, void* data) {
-    T* gps_data = reinterpret_cast<T*>(data);
-    size_t measurementCount = gps_data->measurement_count;
-    if (measurementCount == 0) {
+static jobject translate_gnss_measurement(JNIEnv* env,
+                                          GnssMeasurement* measurement) {
+    JavaObject object(env, "android/location/GnssMeasurement");
+    GpsMeasurementFlags flags = measurement->flags;
+
+    SET(Svid, measurement->svid);
+    SET(TimeOffsetInNs, measurement->time_offset_ns);
+    SET(State, measurement->state);
+    SET(ReceivedGpsTowInNs, measurement->received_gps_tow_ns);
+    SET(ReceivedGpsTowUncertaintyInNs,
+        measurement->received_gps_tow_uncertainty_ns);
+    SET(Cn0InDbHz, measurement->c_n0_dbhz);
+    SET(PseudorangeRateInMetersPerSec, measurement->pseudorange_rate_mps);
+    SET(PseudorangeRateUncertaintyInMetersPerSec,
+        measurement->pseudorange_rate_uncertainty_mps);
+    SET(AccumulatedDeltaRangeState, measurement->accumulated_delta_range_state);
+    SET(AccumulatedDeltaRangeInMeters, measurement->accumulated_delta_range_m);
+    SET(AccumulatedDeltaRangeUncertaintyInMeters,
+        measurement->accumulated_delta_range_uncertainty_m);
+    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE,
+           PseudorangeInMeters,
+           measurement->pseudorange_m);
+    SET_IF(GPS_MEASUREMENT_HAS_PSEUDORANGE_UNCERTAINTY,
+           PseudorangeUncertaintyInMeters,
+           measurement->pseudorange_uncertainty_m);
+    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE,
+           CodePhaseInChips,
+           measurement->code_phase_chips);
+    SET_IF(GPS_MEASUREMENT_HAS_CODE_PHASE_UNCERTAINTY,
+           CodePhaseUncertaintyInChips,
+           measurement->code_phase_uncertainty_chips);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
+           CarrierFrequencyInHz,
+           measurement->carrier_frequency_hz);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_CYCLES,
+           CarrierCycles,
+           measurement->carrier_cycles);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE,
+           CarrierPhase,
+           measurement->carrier_phase);
+    SET_IF(GPS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
+           CarrierPhaseUncertainty,
+           measurement->carrier_phase_uncertainty);
+    SET(LossOfLock, measurement->loss_of_lock);
+    SET_IF(GPS_MEASUREMENT_HAS_BIT_NUMBER, BitNumber, measurement->bit_number);
+    SET_IF(GPS_MEASUREMENT_HAS_TIME_FROM_LAST_BIT,
+           TimeFromLastBitInMs,
+           measurement->time_from_last_bit_ms);
+    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT,
+           DopplerShiftInHz,
+           measurement->doppler_shift_hz);
+    SET_IF(GPS_MEASUREMENT_HAS_DOPPLER_SHIFT_UNCERTAINTY,
+           DopplerShiftUncertaintyInHz,
+           measurement->doppler_shift_uncertainty_hz);
+    SET(MultipathIndicator, measurement->multipath_indicator);
+    SET_IF(GPS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
+    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION,
+           ElevationInDeg,
+           measurement->elevation_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_ELEVATION_UNCERTAINTY,
+           ElevationUncertaintyInDeg,
+           measurement->elevation_uncertainty_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH,
+           AzimuthInDeg,
+           measurement->azimuth_deg);
+    SET_IF(GPS_MEASUREMENT_HAS_AZIMUTH_UNCERTAINTY,
+           AzimuthUncertaintyInDeg,
+           measurement->azimuth_uncertainty_deg);
+    SET(UsedInFix,
+        (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix);
+
+    SET(PseudorangeRateCarrierInMetersPerSec,
+        measurement->pseudorange_rate_carrier_mps);
+    SET(PseudorangeRateCarrierUncertaintyInMetersPerSec,
+        measurement->pseudorange_rate_carrier_uncertainty_mps);
+
+    return object.get();
+}
+
+static jobjectArray translate_gps_measurements(JNIEnv* env,
+                                               GpsMeasurement* measurements,
+                                               size_t count) {
+    if (count == 0) {
         return NULL;
     }
 
-    jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
+    jclass gnssMeasurementClass = env->FindClass(
+            "android/location/GnssMeasurement");
     jobjectArray gnssMeasurementArray = env->NewObjectArray(
-            measurementCount,
+            count,
             gnssMeasurementClass,
             NULL /* initialElement */);
 
-    for (uint16_t i = 0; i < measurementCount; ++i) {
+    for (uint16_t i = 0; i < count; ++i) {
         jobject gnssMeasurement = translate_gps_measurement(
             env,
-            &(gps_data->measurements[i]),
-            sizeof(gps_data->measurements[0]));
+            &measurements[i]);
         env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
         env->DeleteLocalRef(gnssMeasurement);
     }
@@ -1340,27 +1331,37 @@
     return gnssMeasurementArray;
 }
 
-static void measurement_callback(GpsData* data) {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    if (data == NULL) {
-        ALOGE("Invalid data provided to gps_measurement_callback");
-        return;
-    }
-    if (data->size != sizeof(GpsData) && data->size != sizeof(GpsData_v1)) {
-        ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%zd", data->size);
-        return;
+static jobjectArray translate_gnss_measurements(JNIEnv* env,
+                                                GnssMeasurement* measurements,
+                                                size_t count) {
+    if (count == 0) {
+        return NULL;
     }
 
-    jobject gpsClock;
-    jobjectArray measurementArray;
-    if (data->size == sizeof(GpsData)) {
-        gpsClock = translate_gps_clock(env, &data->clock, sizeof(GpsClock));
-        measurementArray = translate_gps_measurements<GpsData>(env, data);
-    } else {
-        gpsClock = translate_gps_clock(env, &data->clock, sizeof(GpsClock_v1));
-        measurementArray = translate_gps_measurements<GpsData_v1>(env, data);
+    jclass gnssMeasurementClass = env->FindClass(
+            "android/location/GnssMeasurement");
+    jobjectArray gnssMeasurementArray = env->NewObjectArray(
+            count,
+            gnssMeasurementClass,
+            NULL /* initialElement */);
+
+    for (uint16_t i = 0; i < count; ++i) {
+        jobject gnssMeasurement = translate_gnss_measurement(
+            env,
+            &measurements[i]);
+        env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
+        env->DeleteLocalRef(gnssMeasurement);
     }
-    jclass gnssMeasurementsEventClass = env->FindClass("android/location/GnssMeasurementsEvent");
+
+    env->DeleteLocalRef(gnssMeasurementClass);
+    return gnssMeasurementArray;
+}
+
+static void set_measurement_data(JNIEnv *env,
+                                 jobject clock,
+                                 jobjectArray measurementArray) {
+    jclass gnssMeasurementsEventClass = env->FindClass(
+            "android/location/GnssMeasurementsEvent");
     jmethodID gnssMeasurementsEventCtor = env->GetMethodID(
         gnssMeasurementsEventClass,
         "<init>",
@@ -1369,21 +1370,68 @@
     jobject gnssMeasurementsEvent = env->NewObject(
         gnssMeasurementsEventClass,
         gnssMeasurementsEventCtor,
-        gpsClock,
+        clock,
         measurementArray);
-
-    env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gnssMeasurementsEvent);
+    env->CallVoidMethod(mCallbacksObj,
+                        method_reportMeasurementData,
+                        gnssMeasurementsEvent);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
-    env->DeleteLocalRef(gpsClock);
-    env->DeleteLocalRef(measurementArray);
     env->DeleteLocalRef(gnssMeasurementsEventClass);
     env->DeleteLocalRef(gnssMeasurementsEvent);
 }
 
+static void measurement_callback(GpsData* data) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (data == NULL) {
+        ALOGE("Invalid data provided to gps_measurement_callback");
+        return;
+    }
+    if (data->size != sizeof(GpsData)) {
+        ALOGE("Invalid GpsData size found in gps_measurement_callback, "
+              "size=%zd",
+              data->size);
+        return;
+    }
+
+    jobject clock;
+    jobjectArray measurementArray;
+    clock = translate_gps_clock(env, &data->clock);
+    measurementArray = translate_gps_measurements(
+            env, data->measurements, data->measurement_count);
+    set_measurement_data(env, clock, measurementArray);
+
+    env->DeleteLocalRef(clock);
+    env->DeleteLocalRef(measurementArray);
+}
+
+static void gnss_measurement_callback(GnssData* data) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    if (data == NULL) {
+        ALOGE("Invalid data provided to gps_measurement_callback");
+        return;
+    }
+    if (data->size != sizeof(GpsData)) {
+        ALOGE("Invalid GpsData size found in gps_measurement_callback, "
+              "size=%zd",
+              data->size);
+        return;
+    }
+
+    jobject clock;
+    jobjectArray measurementArray;
+    clock = translate_gnss_clock(env, &data->clock);
+    measurementArray = translate_gnss_measurements(
+            env, data->measurements, data->measurement_count);
+    set_measurement_data(env, clock, measurementArray);
+
+    env->DeleteLocalRef(clock);
+    env->DeleteLocalRef(measurementArray);
+}
+
 GpsMeasurementCallbacks sGpsMeasurementCallbacks = {
     sizeof(GpsMeasurementCallbacks),
     measurement_callback,
+    gnss_measurement_callback,
 };
 
 static jboolean android_location_GnssLocationProvider_is_measurement_supported(
@@ -1431,69 +1479,86 @@
         ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
         return NULL;
     }
+    JavaObject object(env, "android/location/GnssNavigationMessage");
+    SET(Type, message->type);
+    SET(Svid, static_cast<int16_t>(message->prn));
+    SET(MessageId, message->message_id);
+    SET(SubmessageId, message->submessage_id);
+    object.callSetter("setData", data, dataLength);
+    return object.get();
+}
 
-    jclass navigationMessageClass = env->FindClass("android/location/GnssNavigationMessage");
-    jmethodID navigationMessageCtor = env->GetMethodID(navigationMessageClass, "<init>", "()V");
-    jobject navigationMessageObject = env->NewObject(navigationMessageClass, navigationMessageCtor);
+static jobject translate_gnss_navigation_message(
+        JNIEnv* env, GnssNavigationMessage* message) {
+    size_t dataLength = message->data_length;
+    uint8_t* data = message->data;
+    if (dataLength == 0 || data == NULL) {
+        ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
+        return NULL;
+    }
+    JavaObject object(env, "android/location/GnssNavigationMessage");
+    SET(Type, message->type);
+    SET(Svid, message->svid);
+    SET(MessageId, message->message_id);
+    SET(SubmessageId, message->submessage_id);
+    object.callSetter("setData", data, dataLength);
+    return object.get();
+}
 
-    jmethodID setTypeMethod = env->GetMethodID(navigationMessageClass, "setType", "(B)V");
-    env->CallVoidMethod(navigationMessageObject, setTypeMethod, message->type);
-
-    jmethodID setPrnMethod = env->GetMethodID(navigationMessageClass, "setPrn", "(B)V");
-    env->CallVoidMethod(navigationMessageObject, setPrnMethod, message->prn);
-
-    jmethodID setMessageIdMethod = env->GetMethodID(navigationMessageClass, "setMessageId", "(S)V");
-    env->CallVoidMethod(navigationMessageObject, setMessageIdMethod, message->message_id);
-
-    jmethodID setSubmessageIdMethod =
-            env->GetMethodID(navigationMessageClass, "setSubmessageId", "(S)V");
-    env->CallVoidMethod(navigationMessageObject, setSubmessageIdMethod, message->submessage_id);
-
-    jbyteArray dataArray = env->NewByteArray(dataLength);
-    env->SetByteArrayRegion(dataArray, 0, dataLength, (jbyte*) data);
-    jmethodID setDataMethod = env->GetMethodID(navigationMessageClass, "setData", "([B)V");
-    env->CallVoidMethod(navigationMessageObject, setDataMethod, dataArray);
-
-    env->DeleteLocalRef(navigationMessageClass);
-    env->DeleteLocalRef(dataArray);
-    return navigationMessageObject;
+static void set_navigation_message(jobject navigationMessage) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jclass navigationMessageEventClass =
+            env->FindClass("android/location/GnssNavigationMessageEvent");
+    jmethodID navigationMessageEventCtor = env->GetMethodID(
+            navigationMessageEventClass,
+            "<init>",
+            "(Landroid/location/GnssNavigationMessage;)V");
+    jobject navigationMessageEvent = env->NewObject(
+            navigationMessageEventClass,
+            navigationMessageEventCtor,
+            navigationMessage);
+    env->CallVoidMethod(mCallbacksObj,
+                        method_reportNavigationMessages,
+                        navigationMessageEvent);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(navigationMessageEventClass);
+    env->DeleteLocalRef(navigationMessageEvent);
 }
 
 static void navigation_message_callback(GpsNavigationMessage* message) {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
     if (message == NULL) {
         ALOGE("Invalid Navigation Message provided to callback");
         return;
     }
-
-    if (message->size == sizeof(GpsNavigationMessage)) {
-        jobject navigationMessage = translate_gps_navigation_message(env, message);
-
-        jclass navigationMessageEventClass =
-                env->FindClass("android/location/GnssNavigationMessageEvent");
-        jmethodID navigationMessageEventCtor = env->GetMethodID(
-                navigationMessageEventClass,
-                "<init>",
-                "(Landroid/location/GnssNavigationMessage;)V");
-        jobject navigationMessageEvent = env->NewObject(
-                navigationMessageEventClass,
-                navigationMessageEventCtor,
-                navigationMessage);
-
-        env->CallVoidMethod(mCallbacksObj, method_reportNavigationMessages, navigationMessageEvent);
-        checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
-        env->DeleteLocalRef(navigationMessage);
-        env->DeleteLocalRef(navigationMessageEventClass);
-        env->DeleteLocalRef(navigationMessageEvent);
-    } else {
+    if (message->size != sizeof(GpsNavigationMessage)) {
         ALOGE("Invalid GpsNavigationMessage size found: %zd", message->size);
+        return;
     }
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject navigationMessage = translate_gps_navigation_message(env, message);
+    set_navigation_message(navigationMessage);
+    env->DeleteLocalRef(navigationMessage);
+}
+
+static void gnss_navigation_message_callback(GnssNavigationMessage* message) {
+    if (message == NULL) {
+        ALOGE("Invalid Navigation Message provided to callback");
+        return;
+    }
+    if (message->size != sizeof(GnssNavigationMessage)) {
+        ALOGE("Invalid GnssNavigationMessage size found: %zd", message->size);
+        return;
+    }
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    jobject navigationMessage = translate_gnss_navigation_message(env, message);
+    set_navigation_message(navigationMessage);
+    env->DeleteLocalRef(navigationMessage);
 }
 
 GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = {
     sizeof(GpsNavigationMessageCallbacks),
     navigation_message_callback,
+    gnss_navigation_message_callback,
 };
 
 static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
@@ -1567,7 +1632,7 @@
             "(I)V",
             (void*)android_location_GnssLocationProvider_delete_aiding_data},
     {"native_read_sv_status",
-            "([I[F[F[F[I)I",
+            "([I[F[F[F)I",
             (void*)android_location_GnssLocationProvider_read_sv_status},
     {"native_read_nmea", "([BI)I", (void*)android_location_GnssLocationProvider_read_nmea},
     {"native_inject_time", "(JJI)V", (void*)android_location_GnssLocationProvider_inject_time},
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 3fb5a0d..79d2307 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -32,6 +32,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accounts.AccountManager;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -115,6 +116,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -258,20 +260,27 @@
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.WIFI_ON);
     }
 
-    /** Keyguard features that when set on a profile will affect the profiles parent user. */
+    /**
+     * Keyguard features that when set on a managed profile that doesn't have its own challenge will
+     * affect the profile's parent user. These can also be set on the managed profile's parent DPM
+     * instance.
+     */
     private static final int PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER =
-            // STOPSHIP If the work challenge supports fingerprint, move DISABLE_FINGERPRINT
-            // to PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE?
             DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS
             | DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
 
-    /** Keyguard features that when set on a profile affect the profile content or challenge only */
-    private static final int PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE =
+    /**
+     * Keyguard features that when set on a profile affect the profile content or challenge only.
+     * These cannot be set on the managed profile's parent DPM instance
+     */
+    private static final int PROFILE_KEYGUARD_FEATURES_PROFILE_ONLY =
             DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
 
     /** Keyguard features that are allowed to be set on a managed profile */
     private static final int PROFILE_KEYGUARD_FEATURES =
-            PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER | PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE;
+            PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER | PROFILE_KEYGUARD_FEATURES_PROFILE_ONLY;
+
+    private static final int DEVICE_ADMIN_DEACTIVATE_TIMEOUT = 10000;
 
     final Context mContext;
     final Injector mInjector;
@@ -280,6 +289,13 @@
     final UserManagerInternal mUserManagerInternal;
     private final LockPatternUtils mLockPatternUtils;
 
+    /**
+     * Contains (package-user) pairs to remove. An entry (p, u) implies that removal of package p
+     * is requested for user u.
+     */
+    private final Set<Pair<String, Integer>> mPackagesToRemove =
+            new ArraySet<Pair<String, Integer>>();
+
     final LocalService mLocalService;
 
     // Stores and loads state on device and profile owners.
@@ -325,7 +341,7 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             mInjector.getNotificationManager().cancel(LOG_TAG,
-                    RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID);
+                    RemoteBugreportUtils.NOTIFICATION_ID);
             if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED.equals(action)) {
                 onBugreportSharingAccepted();
             } else if (RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_DECLINED
@@ -426,9 +442,10 @@
                 filterConsent.addAction(
                         RemoteBugreportUtils.ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED);
                 mContext.registerReceiver(mRemoteBugreportConsentReceiver, filterConsent);
-                mInjector.getNotificationManager().notify(
-                        LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
-                        RemoteBugreportUtils.buildRemoteBugreportConsentNotification(mContext));
+                mInjector.getNotificationManager().notify(LOG_TAG,
+                        RemoteBugreportUtils.NOTIFICATION_ID,
+                        RemoteBugreportUtils.buildNotification(mContext,
+                                RemoteBugreportUtils.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED));
             }
             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
                     || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) {
@@ -644,7 +661,7 @@
         int getUid() { return info.getActivityInfo().applicationInfo.uid; }
 
         public UserHandle getUserHandle() {
-            return new UserHandle(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
+            return UserHandle.of(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
         }
 
         void writeToXml(XmlSerializer out)
@@ -1238,7 +1255,9 @@
                     if (packageName == null || packageName.equals(adminPackage)) {
                         if (mIPackageManager.getPackageInfo(adminPackage, 0, userHandle) == null
                                 || mIPackageManager.getReceiverInfo(
-                                    aa.info.getComponent(), 0, userHandle) == null) {
+                                    aa.info.getComponent(),
+                                    PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE,
+                                    userHandle) == null) {
                             removed = true;
                             policy.mAdminList.remove(i);
                             policy.mAdminMap.remove(aa.info.getComponent());
@@ -2014,35 +2033,19 @@
         final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
         if (admin != null) {
             getUserData(userHandle).mRemovingAdmins.add(adminReceiver);
-
             sendAdminCommandLocked(admin,
                     DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED,
                     new BroadcastReceiver() {
                         @Override
                         public void onReceive(Context context, Intent intent) {
-                            synchronized (DevicePolicyManagerService.this) {
-                                int userHandle = admin.getUserHandle().getIdentifier();
-                                DevicePolicyData policy = getUserData(userHandle);
-                                boolean doProxyCleanup = admin.info.usesPolicy(
-                                        DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
-                                policy.mAdminList.remove(admin);
-                                policy.mAdminMap.remove(adminReceiver);
-                                validatePasswordOwnerLocked(policy);
-                                if (doProxyCleanup) {
-                                    resetGlobalProxyLocked(getUserData(userHandle));
-                                }
-                                saveSettingsLocked(userHandle);
-                                updateMaximumTimeToLockLocked(userHandle);
-                                policy.mRemovingAdmins.remove(adminReceiver);
-                            }
-                            // The removed admin might have disabled camera, so update user
-                            // restrictions.
-                            pushUserRestrictions(userHandle);
+                            removeAdminArtifacts(adminReceiver, userHandle);
+                            removePackageIfRequired(adminReceiver.getPackageName(), userHandle);
                         }
                     });
         }
     }
 
+
     public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle,
             boolean throwForMissiongPermission) {
         if (!mHasFeature) {
@@ -2699,6 +2702,10 @@
         if (info == null) {
             throw new IllegalArgumentException("Bad admin: " + adminReceiver);
         }
+        if (!info.getActivityInfo().applicationInfo.isInternal()) {
+            throw new IllegalArgumentException("Only apps in internal storage can be active admin: "
+                    + adminReceiver);
+        }
         synchronized (this) {
             long ident = mInjector.binderClearCallingIdentity();
             try {
@@ -2816,6 +2823,7 @@
             return;
         }
         enforceFullCrossUsersPermission(userHandle);
+        enforceUserUnlocked(userHandle);
         synchronized (this) {
             ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
             if (admin == null) {
@@ -2841,16 +2849,16 @@
         }
     }
 
-    private boolean isAdminApiLevelMOrBelow(@NonNull ComponentName who, int userHandle) {
-        DeviceAdminInfo adminInfo = findAdmin(who, userHandle, false);
-        return adminInfo.getActivityInfo().applicationInfo.targetSdkVersion
-                <= Build.VERSION_CODES.M;
-    }
-
     @Override
     public boolean isSeparateProfileChallengeAllowed(int userHandle) {
         ComponentName profileOwner = getProfileOwner(userHandle);
-        return profileOwner != null && !isAdminApiLevelMOrBelow(profileOwner, userHandle);
+        try {
+            // Profile challenge is supported on N or newer release.
+            return profileOwner != null &&
+                    getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M;
+        } catch (RemoteException e) {
+            return false;
+        }
     }
 
     @Override
@@ -3527,11 +3535,14 @@
 
     @Override
     public int getCurrentFailedPasswordAttempts(int userHandle, boolean parent) {
+        enforceFullCrossUsersPermission(userHandle);
         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, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+            if (!isCallerWithSystemUid()) {
+                // 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, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+            }
 
             DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent));
 
@@ -4195,6 +4206,16 @@
         int userHandle = UserHandle.getCallingUserId();
         synchronized (this) {
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            try {
+                if (getTargetSdk(who.getPackageName(), userHandle) >= Build.VERSION_CODES.N) {
+                    if (installerPackage != null &&
+                            !isPackageInstalledForUser(installerPackage, userHandle)) {
+                        throw new IllegalArgumentException("Package " + installerPackage
+                                + " is not installed on the current user");
+                    }
+                }
+            } catch (RemoteException e) {
+            }
             DevicePolicyData policy = getUserData(userHandle);
             policy.mDelegatedCertInstallerPackage = installerPackage;
             saveSettingsLocked(userHandle);
@@ -4481,7 +4502,8 @@
         }
 
         if (mInjector.securityLogIsLoggingEnabled()) {
-            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 0);
+            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 0,
+                    /*method strength*/ 1);
         }
     }
 
@@ -4511,23 +4533,50 @@
         }
 
         if (mInjector.securityLogIsLoggingEnabled()) {
-            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 1);
+            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 1,
+                    /*method strength*/ 1);
         }
     }
 
     @Override
-    public void reportKeyguardDismissed() {
+    public void reportFailedFingerprintAttempt(int userHandle) {
+        enforceFullCrossUsersPermission(userHandle);
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
         if (mInjector.securityLogIsLoggingEnabled()) {
+            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 0,
+                    /*method strength*/ 0);
+        }
+    }
+
+    @Override
+    public void reportSuccessfulFingerprintAttempt(int userHandle) {
+        enforceFullCrossUsersPermission(userHandle);
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+        if (mInjector.securityLogIsLoggingEnabled()) {
+            SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 1,
+                    /*method strength*/ 0);
+        }
+    }
+
+    @Override
+    public void reportKeyguardDismissed(int userHandle) {
+        enforceFullCrossUsersPermission(userHandle);
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+
+        if (mInjector.securityLogIsLoggingEnabled()) {
             SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISSED);
         }
     }
 
     @Override
-    public void reportKeyguardSecured() {
+    public void reportKeyguardSecured(int userHandle) {
+        enforceFullCrossUsersPermission(userHandle);
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
+
         if (mInjector.securityLogIsLoggingEnabled()) {
             SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_SECURED);
         }
@@ -5006,13 +5055,9 @@
             mRemoteBugreportServiceIsActive.set(true);
             mRemoteBugreportSharingAccepted.set(false);
             registerRemoteBugreportReceivers();
-            mInjector.getNotificationManager().notify(
-                    LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
-                    RemoteBugreportUtils.buildRemoteBugreportConsentNotification(mContext));
-            mInjector.getNotificationManager().notify(
-                    LOG_TAG, RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
-                    RemoteBugreportUtils.buildRemoteBugreportInProgressNotification(mContext,
-                            /* canCancelBugReport */ true));
+            mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildNotification(mContext,
+                            RemoteBugreportUtils.NOTIFICATION_BUGREPORT_STARTED));
             mHandler.postDelayed(mRemoteBugreportTimeoutRunnable,
                     RemoteBugreportUtils.REMOTE_BUGREPORT_TIMEOUT_MILLIS);
             return true;
@@ -5062,8 +5107,6 @@
     private void onBugreportFinished(Intent intent) {
         mHandler.removeCallbacks(mRemoteBugreportTimeoutRunnable);
         mRemoteBugreportServiceIsActive.set(false);
-        mInjector.getNotificationManager().cancel(LOG_TAG,
-                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
         Uri bugreportUri = intent.getData();
         String bugreportUriString = null;
         if (bugreportUri != null) {
@@ -5073,8 +5116,13 @@
                 RemoteBugreportUtils.EXTRA_REMOTE_BUGREPORT_HASH);
         if (mRemoteBugreportSharingAccepted.get()) {
             shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash);
+            mInjector.getNotificationManager().cancel(LOG_TAG,
+                    RemoteBugreportUtils.NOTIFICATION_ID);
         } else {
             setDeviceOwnerRemoteBugreportUriAndHash(bugreportUriString, bugreportHash);
+            mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildNotification(mContext,
+                            RemoteBugreportUtils.NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED));
         }
         mContext.unregisterReceiver(mRemoteBugreportFinishedReceiver);
     }
@@ -5085,10 +5133,7 @@
                 RemoteBugreportUtils.REMOTE_BUGREPORT_SERVICE);
         mRemoteBugreportSharingAccepted.set(false);
         setDeviceOwnerRemoteBugreportUriAndHash(null, null);
-        mInjector.getNotificationManager().cancel(LOG_TAG,
-                RemoteBugreportUtils.REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID);
-        mInjector.getNotificationManager().cancel(LOG_TAG,
-                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
+        mInjector.getNotificationManager().cancel(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID);
         Bundle extras = new Bundle();
         extras.putInt(DeviceAdminReceiver.EXTRA_BUGREPORT_FAILURE_REASON,
                 DeviceAdminReceiver.BUGREPORT_FAILURE_FAILED_COMPLETING);
@@ -5108,10 +5153,9 @@
         if (bugreportUriString != null) {
             shareBugreportWithDeviceOwnerIfExists(bugreportUriString, bugreportHash);
         } else if (mRemoteBugreportServiceIsActive.get()) {
-            mInjector.getNotificationManager().notify(LOG_TAG,
-                    RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
-                    RemoteBugreportUtils.buildRemoteBugreportInProgressNotification(mContext,
-                            /* canCancelBugReport */ false));
+            mInjector.getNotificationManager().notify(LOG_TAG, RemoteBugreportUtils.NOTIFICATION_ID,
+                    RemoteBugreportUtils.buildNotification(mContext,
+                            RemoteBugreportUtils.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED));
         }
     }
 
@@ -5125,8 +5169,6 @@
         }
         mRemoteBugreportSharingAccepted.set(false);
         setDeviceOwnerRemoteBugreportUriAndHash(null, null);
-        mInjector.getNotificationManager().cancel(LOG_TAG,
-                RemoteBugreportUtils.REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID);
         sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_BUGREPORT_SHARING_DECLINED, null);
     }
 
@@ -5240,8 +5282,6 @@
         if (isManagedProfile(userHandle)) {
             if (parent) {
                 which = which & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
-            } else if (isSeparateProfileChallengeEnabled(userHandle)){
-                which = which & PROFILE_KEYGUARD_FEATURES_AFFECT_PROFILE;
             } else {
                 which = which & PROFILE_KEYGUARD_FEATURES;
             }
@@ -5289,7 +5329,8 @@
                 for (int i = 0; i < N; i++) {
                     ActiveAdmin admin = admins.get(i);
                     int userId = admin.getUserHandle().getIdentifier();
-                    if (userId == userHandle || !isManagedProfile(userHandle)) {
+                    boolean isRequestedUser = !parent && (userId == userHandle);
+                    if (isRequestedUser || !isManagedProfile(userId)) {
                         // If we are being asked explicitly about this user
                         // return all disabled features even if its a managed profile.
                         which |= admin.disabledKeyguardFeatures;
@@ -5489,6 +5530,7 @@
                 throw new SecurityException(
                         "clearDeviceOwner can only be called by the device owner");
             }
+            enforceUserUnlocked(deviceOwnerUserId);
 
             final ActiveAdmin admin = getDeviceOwnerAdminLocked();
             if (admin != null) {
@@ -5543,6 +5585,7 @@
         final UserHandle callingUser = mInjector.binderGetCallingUserHandle();
         final int userId = callingUser.getIdentifier();
         enforceNotManagedProfile(userId, "clear profile owner");
+        enforceUserUnlocked(userId);
         // Check if this is the profile owner who is calling
         final ActiveAdmin admin =
                 getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5918,6 +5961,11 @@
         }
     }
 
+    private void enforceUserUnlocked(int userId) {
+        Preconditions.checkState(mUserManager.isUserUnlocked(userId),
+                "User must be running and unlocked");
+    }
+
     private void enforceManageUsers() {
         final int callingUid = mInjector.binderGetCallingUid();
         if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) {
@@ -6093,9 +6141,15 @@
 
     @Override
     public void setApplicationRestrictionsManagingPackage(ComponentName admin, String packageName) {
+        Preconditions.checkNotNull(admin, "ComponentName is null");
+
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+            if (packageName != null && !isPackageInstalledForUser(packageName, userHandle)) {
+                throw new IllegalArgumentException("Package " + packageName + " is not installed "
+                        + "on the current user");
+            }
             DevicePolicyData policy = getUserData(userHandle);
             policy.mApplicationRestrictionsManagingPackage = packageName;
             saveSettingsLocked(userHandle);
@@ -6104,6 +6158,8 @@
 
     @Override
     public String getApplicationRestrictionsManagingPackage(ComponentName admin) {
+        Preconditions.checkNotNull(admin, "ComponentName is null");
+
         final int userHandle = mInjector.userHandleGetCallingUserId();
         synchronized (this) {
             getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -6750,6 +6806,10 @@
             throw new IllegalArgumentException("profileOwner " + profileOwner + " and admin "
                     + admin + " are not in the same package");
         }
+        // Only allow the system user to use this method
+        if (!mInjector.binderGetCallingUserHandle().isSystem()) {
+            throw new SecurityException("createAndManageUser was called from non-system user");
+        }
         // Create user.
         UserHandle user = null;
         synchronized (this) {
@@ -6761,7 +6821,8 @@
                 if ((flags & DevicePolicyManager.MAKE_USER_EPHEMERAL) != 0) {
                     userInfoFlags |= UserInfo.FLAG_EPHEMERAL;
                 }
-                UserInfo userInfo = mUserManager.createUser(name, userInfoFlags);
+                UserInfo userInfo = mUserManagerInternal.createUserEvenWhenDisallowed(name,
+                        userInfoFlags);
                 if (userInfo != null) {
                     user = userInfo.getUserHandle();
                 }
@@ -6867,7 +6928,7 @@
     }
 
     @Override
-    public boolean setPackageSuspended(ComponentName who, String packageName,
+    public String[] setPackagesSuspended(ComponentName who, String[] packageNames,
             boolean suspended) {
         Preconditions.checkNotNull(who, "ComponentName is null");
         int callingUserId = UserHandle.getCallingUserId();
@@ -6876,15 +6937,15 @@
 
             long id = mInjector.binderClearCallingIdentity();
             try {
-                return mIPackageManager.setPackageSuspendedAsUser(
-                        packageName, suspended, callingUserId);
+                return mIPackageManager.setPackagesSuspendedAsUser(
+                        packageNames, suspended, callingUserId);
             } catch (RemoteException re) {
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed talking to the package manager", re);
             } finally {
                 mInjector.binderRestoreCallingIdentity(id);
             }
-            return false;
+            return packageNames;
         }
     }
 
@@ -6897,10 +6958,7 @@
 
             long id = mInjector.binderClearCallingIdentity();
             try {
-                ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(
-                        packageName, 0, callingUserId);
-                return appInfo != null &&
-                        (appInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
+                return mIPackageManager.isPackageSuspendedForUser(packageName, callingUserId);
             } catch (RemoteException re) {
                 // Shouldn't happen.
                 Slog.e(LOG_TAG, "Failed talking to the package manager", re);
@@ -7091,7 +7149,7 @@
                 List<ResolveInfo> activitiesToEnable = mIPackageManager.queryIntentActivities(
                         intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                        0, // no flags
+                        PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE,
                         parentUserId);
 
                 if (VERBOSE_LOG) {
@@ -7990,7 +8048,8 @@
 
     boolean isPackageInstalledForUser(String packageName, int userHandle) {
         try {
-            PackageInfo pi = mIPackageManager.getPackageInfo(packageName, 0, userHandle);
+            PackageInfo pi = mInjector.getIPackageManager().getPackageInfo(packageName, 0,
+                    userHandle);
             return (pi != null) && (pi.applicationInfo.flags != 0);
         } catch (RemoteException re) {
             throw new RuntimeException("Package manager has died", re);
@@ -8084,7 +8143,7 @@
 
     private boolean hasFeatureManagedUsers() {
         try {
-            return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+            return mIPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0);
         } catch (RemoteException e) {
             return false;
         }
@@ -8273,6 +8332,21 @@
     }
 
     @Override
+    public void setOrganizationColorForUser(int color, int userId) {
+        if (!mHasFeature) {
+            return;
+        }
+        enforceFullCrossUsersPermission(userId);
+        enforceManageUsers();
+        enforceManagedProfile(userId, "set organization color");
+        synchronized (this) {
+            ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
+            admin.organizationColor = color;
+            saveSettingsLocked(userId);
+        }
+    }
+
+    @Override
     public int getOrganizationColor(@NonNull ComponentName who) {
         if (!mHasFeature) {
             return ActiveAdmin.DEF_ORGANIZATION_COLOR;
@@ -8446,4 +8520,139 @@
         List<SecurityEvent> logs = mSecurityLogMonitor.retrieveLogs();
         return logs != null ? new ParceledListSlice<SecurityEvent>(logs) : null;
     }
+
+    private void enforceCanManageDeviceAdmin() {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS,
+                null);
+    }
+
+    @Override
+    public boolean isUninstallInQueue(final String packageName) {
+        enforceCanManageDeviceAdmin();
+        final int userId = mInjector.userHandleGetCallingUserId();
+        Pair<String, Integer> packageUserPair = new Pair<>(packageName, userId);
+        synchronized (this) {
+            return mPackagesToRemove.contains(packageUserPair);
+        }
+    }
+
+    @Override
+    public void uninstallPackageWithActiveAdmins(final String packageName) {
+        enforceCanManageDeviceAdmin();
+        Preconditions.checkArgument(!TextUtils.isEmpty(packageName));
+
+        final int userId = mInjector.userHandleGetCallingUserId();
+
+        enforceUserUnlocked(userId);
+
+        final ComponentName profileOwner = getProfileOwner(userId);
+        if (profileOwner != null && packageName.equals(profileOwner.getPackageName())) {
+            throw new IllegalArgumentException("Cannot uninstall a package with a profile owner");
+        }
+
+        final ComponentName deviceOwner = getDeviceOwnerComponent(/* callingUserOnly= */ false);
+        if (getDeviceOwnerUserId() == userId && deviceOwner != null
+                && packageName.equals(deviceOwner.getPackageName())) {
+            throw new IllegalArgumentException("Cannot uninstall a package with a device owner");
+        }
+
+        final Pair<String, Integer> packageUserPair = new Pair<>(packageName, userId);
+        synchronized (this) {
+            mPackagesToRemove.add(packageUserPair);
+        }
+
+        // All active admins on the user.
+        final List<ComponentName> allActiveAdmins = getActiveAdmins(userId);
+
+        // Active admins in the target package.
+        final List<ComponentName> packageActiveAdmins = new ArrayList<>();
+        if (allActiveAdmins != null) {
+            for (ComponentName activeAdmin : allActiveAdmins) {
+                if (packageName.equals(activeAdmin.getPackageName())) {
+                    packageActiveAdmins.add(activeAdmin);
+                    removeActiveAdmin(activeAdmin, userId);
+                }
+            }
+        }
+        if (packageActiveAdmins.size() == 0) {
+            startUninstallIntent(packageName, userId);
+        } else {
+            mHandler.postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    for (ComponentName activeAdmin : packageActiveAdmins) {
+                        removeAdminArtifacts(activeAdmin, userId);
+                    }
+                    startUninstallIntent(packageName, userId);
+                }
+            }, DEVICE_ADMIN_DEACTIVATE_TIMEOUT); // Start uninstall after timeout anyway.
+        }
+    }
+
+    private void removePackageIfRequired(final String packageName, final int userId) {
+        if (!packageHasActiveAdmins(packageName, userId)) {
+            // Will not do anything if uninstall was not requested or was already started.
+            startUninstallIntent(packageName, userId);
+        }
+    }
+
+    private void startUninstallIntent(final String packageName, final int userId) {
+        final Pair<String, Integer> packageUserPair = new Pair<>(packageName, userId);
+        synchronized (this) {
+            if (!mPackagesToRemove.contains(packageUserPair)) {
+                // Do nothing if uninstall was not requested or was already started.
+                return;
+            }
+            mPackagesToRemove.remove(packageUserPair);
+        }
+        try {
+            if (mInjector.getIPackageManager().getPackageInfo(packageName, 0, userId) == null) {
+                // Package does not exist. Nothing to do.
+                return;
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Failure talking to PackageManager while getting package info");
+        }
+
+        try { // force stop the package before uninstalling
+            mInjector.getIActivityManager().forceStopPackage(packageName, userId);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Failure talking to ActivityManager while force stopping package");
+        }
+        final Uri packageURI = Uri.parse("package:" + packageName);
+        final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI);
+        uninstallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivityAsUser(uninstallIntent, UserHandle.of(userId));
+    }
+
+    /**
+     * Removes the admin from the policy. Ideally called after the admin's
+     * {@link DeviceAdminReceiver#onDisabled(Context, Intent)} has been successfully completed.
+     *
+     * @param adminReceiver The admin to remove
+     * @param userHandle The user for which this admin has to be removed.
+     */
+    private void removeAdminArtifacts(final ComponentName adminReceiver, final int userHandle) {
+        synchronized (this) {
+            final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
+            if (admin == null) {
+                return;
+            }
+            final DevicePolicyData policy = getUserData(userHandle);
+            final boolean doProxyCleanup = admin.info.usesPolicy(
+                    DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
+            policy.mAdminList.remove(admin);
+            policy.mAdminMap.remove(adminReceiver);
+            validatePasswordOwnerLocked(policy);
+            if (doProxyCleanup) {
+                resetGlobalProxyLocked(policy);
+            }
+            saveSettingsLocked(userHandle);
+            updateMaximumTimeToLockLocked(userHandle);
+            policy.mRemovingAdmins.remove(adminReceiver);
+        }
+        // The removed admin might have disabled camera, so update user
+        // restrictions.
+        pushUserRestrictions(userHandle);
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index 880f810..68fd0f6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -716,11 +716,11 @@
     }
 
     File getLegacyConfigFileWithTestOverride() {
-        return new File(Environment.getSystemSecureDirectory(), DEVICE_OWNER_XML_LEGACY);
+        return new File(Environment.getDataSystemDirectory(), DEVICE_OWNER_XML_LEGACY);
     }
 
     File getDeviceOwnerFileWithTestOverride() {
-        return new File(Environment.getSystemSecureDirectory(), DEVICE_OWNER_XML);
+        return new File(Environment.getDataSystemDirectory(), DEVICE_OWNER_XML);
     }
 
     File getProfileOwnerFileWithTestOverride(int userId) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
index 3e1fbc7..117ba15 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
@@ -16,6 +16,7 @@
 
 package com.android.server.devicepolicy;
 
+import android.annotation.IntDef;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -24,13 +25,26 @@
 
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Utilities class for the remote bugreport operation.
  */
 class RemoteBugreportUtils {
 
-    static final int REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID = 678435657;
-    static final int REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID = 590907895;
+    static final int NOTIFICATION_ID = 678432343;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        NOTIFICATION_BUGREPORT_STARTED,
+        NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED,
+        NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED
+    })
+    @interface RemoteBugreportNotificationType {}
+    static final int NOTIFICATION_BUGREPORT_STARTED = 1;
+    static final int NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED = 2;
+    static final int NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED = 3;
 
     static final long REMOTE_BUGREPORT_TIMEOUT_MILLIS = 10 * DateUtils.MINUTE_IN_MILLIS;
 
@@ -47,65 +61,57 @@
 
     static final String BUGREPORT_MIMETYPE = "application/vnd.android.bugreport";
 
-    static Notification buildRemoteBugreportConsentNotification(Context context) {
-        PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(
-                context, REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
-                new Intent(ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED),
-                        PendingIntent.FLAG_CANCEL_CURRENT);
-        PendingIntent pendingIntentDecline = PendingIntent.getBroadcast(
-                context, REMOTE_BUGREPORT_CONSENT_NOTIFICATION_ID,
-                new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED),
-                        PendingIntent.FLAG_CANCEL_CURRENT);
-
-        return new Notification.Builder(context)
-                .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                .setContentTitle(context.getString(
-                        R.string.share_remote_bugreport_notification_title))
-                .setTicker(context.getString(R.string.share_remote_bugreport_notification_title))
-                .setContentText(context.getString(
-                        R.string.share_remote_bugreport_notification_message))
-                .setStyle(new Notification.BigTextStyle().bigText(context.getString(
-                        R.string.share_remote_bugreport_notification_message)))
-                .addAction(new Notification.Action.Builder(null /* icon */,
-                        context.getString(R.string.share_remote_bugreport_notification_decline),
-                        pendingIntentDecline).build())
-                .addAction(new Notification.Action.Builder(null /* icon */,
-                        context.getString(R.string.share_remote_bugreport_notification_accept),
-                        pendingIntentAccept).build())
-                .setOngoing(true)
-                .setLocalOnly(true)
-                .setColor(context.getColor(
-                        com.android.internal.R.color.system_notification_accent_color))
-                .setPriority(Notification.PRIORITY_MAX)
-                .setVibrate(new long[0])
-                .build();
-    }
-
-    static Notification buildRemoteBugreportInProgressNotification(Context context,
-            boolean canCancelBugreport) {
+    static Notification buildNotification(Context context,
+            @RemoteBugreportNotificationType int type) {
         Notification.Builder builder = new Notification.Builder(context)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                .setContentTitle(context.getString(
-                        R.string.remote_bugreport_progress_notification_title))
-                .setTicker(context.getString(
-                        R.string.remote_bugreport_progress_notification_title))
                 .setOngoing(true)
                 .setLocalOnly(true)
                 .setColor(context.getColor(
-                        com.android.internal.R.color.system_notification_accent_color))
-                .setPriority(Notification.PRIORITY_HIGH);
+                        com.android.internal.R.color.system_notification_accent_color));
 
-        if (canCancelBugreport) {
-            PendingIntent pendingIntentCancel = PendingIntent.getBroadcast(context,
-                    REMOTE_BUGREPORT_IN_PROGRESS_NOTIFICATION_ID,
-                    new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED),
+        if (type == NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED) {
+            builder.setContentTitle(context.getString(
+                            R.string.sharing_remote_bugreport_notification_title))
+                    .setContentText(context.getString(
+                            R.string.sharing_remote_bugreport_notification_message))
+                    .setPriority(Notification.PRIORITY_HIGH)
+                    .setProgress(0, 0, true)
+                    .setStyle(new Notification.BigTextStyle().bigText(context.getString(
+                            R.string.sharing_remote_bugreport_notification_message)));
+        } else {
+            PendingIntent pendingIntentAccept = PendingIntent.getBroadcast(context, NOTIFICATION_ID,
+                    new Intent(ACTION_REMOTE_BUGREPORT_SHARING_ACCEPTED),
                     PendingIntent.FLAG_CANCEL_CURRENT);
-            String message = context.getString(
-                    R.string.remote_bugreport_progress_notification_message_can_cancel);
-            builder.setContentText(message)
-                    .setContentIntent(pendingIntentCancel)
-                    .setStyle(new Notification.BigTextStyle().bigText(message));
+            PendingIntent pendingIntentDecline = PendingIntent.getBroadcast(context,
+                    NOTIFICATION_ID, new Intent(ACTION_REMOTE_BUGREPORT_SHARING_DECLINED),
+                    PendingIntent.FLAG_CANCEL_CURRENT);
+            builder.addAction(new Notification.Action.Builder(null /* icon */, context.getString(
+                            R.string.share_remote_bugreport_notification_decline),
+                            pendingIntentDecline).build())
+                    .addAction(new Notification.Action.Builder(null /* icon */, context.getString(
+                            R.string.share_remote_bugreport_notification_accept),
+                            pendingIntentAccept).build())
+                    .setContentTitle(context.getString(
+                            R.string.share_remote_bugreport_notification_title));
+
+            if (type == NOTIFICATION_BUGREPORT_STARTED) {
+                builder.setContentText(context.getString(
+                                R.string.share_remote_bugreport_notification_message))
+                        .setStyle(new Notification.BigTextStyle().bigText(context.getString(
+                                R.string.share_remote_bugreport_notification_message)))
+                        .setProgress(0, 0, true)
+                        .setPriority(Notification.PRIORITY_MAX)
+                        .setVibrate(new long[0]);
+            } else if (type == NOTIFICATION_BUGREPORT_FINISHED_NOT_ACCEPTED) {
+                builder.setContentText(context.getString(
+                                R.string.share_finished_remote_bugreport_notification_message))
+                        .setStyle(new Notification.BigTextStyle().bigText(context.getString(
+                                R.string.share_finished_remote_bugreport_notification_message)))
+                        .setPriority(Notification.PRIORITY_HIGH);
+            }
         }
+
         return builder.build();
     }
 }
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index 2329b42..38551b6 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -25,9 +25,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.net.DhcpResults;
 import android.net.BaseDhcpStateMachine;
-import android.net.DhcpStateMachine;
+import android.net.DhcpResults;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.NetworkUtils;
@@ -103,12 +102,35 @@
     // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter.
     private static final int DHCP_TIMEOUT_MS    =  36 * SECONDS;
 
+    private static final int PUBLIC_BASE = Protocol.BASE_DHCP;
+
+    /* Commands from controller to start/stop DHCP */
+    public static final int CMD_START_DHCP                  = PUBLIC_BASE + 1;
+    public static final int CMD_STOP_DHCP                   = PUBLIC_BASE + 2;
+    public static final int CMD_RENEW_DHCP                  = PUBLIC_BASE + 3;
+
+    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
+    public static final int CMD_PRE_DHCP_ACTION             = PUBLIC_BASE + 4;
+    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
+     * success/failure */
+    public static final int CMD_POST_DHCP_ACTION            = PUBLIC_BASE + 5;
+    /* Notification from DHCP state machine before quitting */
+    public static final int CMD_ON_QUIT                     = PUBLIC_BASE + 6;
+
+    /* Command from controller to indicate DHCP discovery/renewal can continue
+     * after pre DHCP action is complete */
+    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = PUBLIC_BASE + 7;
+
+    /* Message.arg1 arguments to CMD_POST_DHCP notification */
+    public static final int DHCP_SUCCESS = 1;
+    public static final int DHCP_FAILURE = 2;
+
     // Messages.
-    private static final int BASE                 = Protocol.BASE_DHCP + 100;
-    private static final int CMD_KICK             = BASE + 1;
-    private static final int CMD_RECEIVED_PACKET  = BASE + 2;
-    private static final int CMD_TIMEOUT          = BASE + 3;
-    private static final int CMD_ONESHOT_TIMEOUT  = BASE + 4;
+    private static final int PRIVATE_BASE         = Protocol.BASE_DHCP + 100;
+    private static final int CMD_KICK             = PRIVATE_BASE + 1;
+    private static final int CMD_RECEIVED_PACKET  = PRIVATE_BASE + 2;
+    private static final int CMD_TIMEOUT          = PRIVATE_BASE + 3;
+    private static final int CMD_ONESHOT_TIMEOUT  = PRIVATE_BASE + 4;
 
     // DHCP parameters that we request.
     private static final byte[] REQUESTED_PARAMS = new byte[] {
@@ -211,7 +233,7 @@
         // Used to time out PacketRetransmittingStates.
         mTimeoutAlarm = makeWakeupMessage("TIMEOUT", CMD_TIMEOUT);
         // Used to schedule DHCP renews.
-        mRenewAlarm = makeWakeupMessage("RENEW", DhcpStateMachine.CMD_RENEW_DHCP);
+        mRenewAlarm = makeWakeupMessage("RENEW", CMD_RENEW_DHCP);
         // Used to tell the caller when its request (CMD_START_DHCP or CMD_RENEW_DHCP) timed out.
         // TODO: when the legacy DHCP client is gone, make the client fully asynchronous and
         // remove this.
@@ -225,6 +247,11 @@
 
     public static BaseDhcpStateMachine makeDhcpStateMachine(
             Context context, StateMachine controller, String intf) {
+        return makeDhcpClient(context, controller, intf);
+    }
+
+    public static DhcpClient makeDhcpClient(
+            Context context, StateMachine controller, String intf) {
         DhcpClient client = new DhcpClient(context, controller, intf);
         client.start();
         return client;
@@ -400,13 +427,12 @@
     }
 
     private void notifySuccess() {
-        mController.sendMessage(DhcpStateMachine.CMD_POST_DHCP_ACTION,
-                DhcpStateMachine.DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
+        mController.sendMessage(
+                CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, new DhcpResults(mDhcpLease));
     }
 
     private void notifyFailure() {
-        mController.sendMessage(DhcpStateMachine.CMD_POST_DHCP_ACTION,
-                DhcpStateMachine.DHCP_FAILURE, 0, null);
+        mController.sendMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0, null);
     }
 
     private void clearDhcpState() {
@@ -428,7 +454,7 @@
 
     protected void onQuitting() {
         Log.d(TAG, "onQuitting");
-        mController.sendMessage(DhcpStateMachine.CMD_ON_QUIT);
+        mController.sendMessage(CMD_ON_QUIT);
     }
 
     private void maybeLog(String msg) {
@@ -442,17 +468,17 @@
 
         private String messageName(int what) {
             switch (what) {
-                case DhcpStateMachine.CMD_START_DHCP:
+                case CMD_START_DHCP:
                     return "CMD_START_DHCP";
-                case DhcpStateMachine.CMD_STOP_DHCP:
+                case CMD_STOP_DHCP:
                     return "CMD_STOP_DHCP";
-                case DhcpStateMachine.CMD_RENEW_DHCP:
+                case CMD_RENEW_DHCP:
                     return "CMD_RENEW_DHCP";
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
+                case CMD_PRE_DHCP_ACTION:
                     return "CMD_PRE_DHCP_ACTION";
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE:
+                case CMD_PRE_DHCP_ACTION_COMPLETE:
                     return "CMD_PRE_DHCP_ACTION_COMPLETE";
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
+                case CMD_POST_DHCP_ACTION:
                     return "CMD_POST_DHCP_ACTION";
                 case CMD_KICK:
                     return "CMD_KICK";
@@ -495,14 +521,14 @@
         @Override
         public void enter() {
             super.enter();
-            mController.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION);
+            mController.sendMessage(CMD_PRE_DHCP_ACTION);
         }
 
         @Override
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE:
+                case CMD_PRE_DHCP_ACTION_COMPLETE:
                     transitionTo(mOtherState);
                     return HANDLED;
                 default:
@@ -532,7 +558,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_START_DHCP:
+                case CMD_START_DHCP:
                     scheduleOneshotTimeout();
                     if (mRegisteredForPreDhcpNotification) {
                         transitionTo(mWaitBeforeStartState);
@@ -588,7 +614,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_STOP_DHCP:
+                case CMD_STOP_DHCP:
                     transitionTo(mStoppedState);
                     return HANDLED;
                 case CMD_ONESHOT_TIMEOUT:
@@ -801,7 +827,7 @@
             super.enter();
             mOneshotTimeoutAlarm.cancel();
             notifySuccess();
-            // TODO: DhcpStateMachine only supports renewing at 50% of the lease time, and does not
+            // TODO: DhcpStateMachine only supported renewing at 50% of the lease time, and did not
             // support rebinding. Once the legacy DHCP client is gone, fix this.
             scheduleRenew();
         }
@@ -810,7 +836,7 @@
         public boolean processMessage(Message message) {
             super.processMessage(message);
             switch (message.what) {
-                case DhcpStateMachine.CMD_RENEW_DHCP:
+                case CMD_RENEW_DHCP:
                     if (mRegisteredForPreDhcpNotification) {
                         transitionTo(mWaitBeforeRenewalState);
                     } else {
@@ -869,7 +895,7 @@
         }
     }
 
-    // Not implemented. DhcpStateMachine does not implement it either.
+    // Not implemented. DhcpStateMachine did not implement it either.
     class DhcpRebindingState extends LoggingState {
     }
 
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 06b6ee7..d0d87b1 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -17,9 +17,7 @@
 package android.net.ip;
 
 import android.content.Context;
-import android.net.BaseDhcpStateMachine;
 import android.net.DhcpResults;
-import android.net.DhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
@@ -31,7 +29,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.Settings;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -61,44 +58,29 @@
  * @hide
  */
 public class IpManager extends StateMachine {
-    private static final String TAG = IpManager.class.getSimpleName();
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
     /**
-     * Callbacks for both configuration of IpManager and for handling
-     * events as desired.
+     * Callbacks for handling IpManager events.
      */
     public static class Callback {
-        /**
-         * Configuration callbacks.
-         *
-         * Override methods as desired in order to control which features
-         * IpManager will use at run time.
-         */
-
-        // An IpReachabilityMonitor will always be started, if only for logging.
-        // This method is checked before probing neighbors and before calling
-        // onProvisioningLost() (see below).
-        public boolean usingIpReachabilityMonitor() {
-            return false;
-        }
-
-        /**
-         * Event callbacks.
-         *
-         * Override methods as desired in order to handle event callbacks
-         * as IpManager invokes them.
-         */
-
-        // Implementations must call IpManager#completedPreDhcpAction().
+        // In order to receive onPreDhcpAction(), call #withPreDhcpAction()
+        // when constructing a ProvisioningConfiguration.
+        //
+        // Implementations of onPreDhcpAction() must call
+        // IpManager#completedPreDhcpAction() to indicate that DHCP is clear
+        // to proceed.
         public void onPreDhcpAction() {}
         public void onPostDhcpAction() {}
 
-        // TODO: Kill with fire once DHCP and static configuration are moved
-        // out of WifiStateMachine.
-        public void onIPv4ProvisioningSuccess(DhcpResults dhcpResults) {}
-        public void onIPv4ProvisioningFailure() {}
+        // This is purely advisory and not an indication of provisioning
+        // success or failure.  This is only here for callers that want to
+        // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
+        // DHCPv4 or static IPv4 configuration failure or success can be
+        // determined by whether or not the passed-in DhcpResults object is
+        // null or not.
+        public void onNewDhcpResults(DhcpResults dhcpResults) {}
 
         public void onProvisioningSuccess(LinkProperties newLp) {}
         public void onProvisioningFailure(LinkProperties newLp) {}
@@ -109,6 +91,67 @@
         // Called when the internal IpReachabilityMonitor (if enabled) has
         // detected the loss of a critical number of required neighbors.
         public void onReachabilityLost(String logMsg) {}
+
+        // Called when the IpManager state machine terminates.
+        public void onQuit() {}
+    }
+
+    /**
+     * This class encapsulates parameters to be passed to
+     * IpManager#startProvisioning(). A defensive copy is made by IpManager
+     * and the values specified herein are in force until IpManager#stop()
+     * is called.
+     *
+     * Example use:
+     *
+     *     final ProvisioningConfiguration config =
+     *             mIpManager.buildProvisioningConfiguration()
+     *                     .withPreDhcpAction()
+     *                     .build();
+     *     mIpManager.startProvisioning(config);
+     *     ...
+     *     mIpManager.stop();
+     *
+     * The specified provisioning configuration will only be active until
+     * IpManager#stop() is called. Future calls to IpManager#startProvisioning()
+     * must specify the configuration again.
+     */
+    public static class ProvisioningConfiguration {
+
+        public static class Builder {
+            private ProvisioningConfiguration mConfig = new ProvisioningConfiguration();
+
+            public Builder withoutIpReachabilityMonitor() {
+                mConfig.mUsingIpReachabilityMonitor = false;
+                return this;
+            }
+
+            public Builder withPreDhcpAction() {
+                mConfig.mRequestedPreDhcpAction = true;
+                return this;
+            }
+
+            public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) {
+                mConfig.mStaticIpConfig = staticConfig;
+                return this;
+            }
+
+            public ProvisioningConfiguration build() {
+                return new ProvisioningConfiguration(mConfig);
+            }
+        }
+
+        /* package */ boolean mUsingIpReachabilityMonitor = true;
+        /* package */ boolean mRequestedPreDhcpAction;
+        /* package */ StaticIpConfiguration mStaticIpConfig;
+
+        public ProvisioningConfiguration() {}
+
+        public ProvisioningConfiguration(ProvisioningConfiguration other) {
+            mUsingIpReachabilityMonitor = other.mUsingIpReachabilityMonitor;
+            mRequestedPreDhcpAction = other.mRequestedPreDhcpAction;
+            mStaticIpConfig = other.mStaticIpConfig;
+        }
     }
 
     private static final int CMD_STOP = 1;
@@ -122,8 +165,10 @@
 
     private final Object mLock = new Object();
     private final State mStoppedState = new StoppedState();
+    private final State mStoppingState = new StoppingState();
     private final State mStartedState = new StartedState();
 
+    private final String mTag;
     private final Context mContext;
     private final String mInterfaceName;
     @VisibleForTesting
@@ -137,9 +182,9 @@
      * Non-final member variables accessed only from within our StateMachine.
      */
     private IpReachabilityMonitor mIpReachabilityMonitor;
-    private BaseDhcpStateMachine mDhcpStateMachine;
+    private DhcpClient mDhcpClient;
     private DhcpResults mDhcpResults;
-    private StaticIpConfiguration mStaticIpConfig;
+    private ProvisioningConfiguration mConfiguration;
 
     /**
      * Member variables accessed both from within the StateMachine thread
@@ -150,11 +195,11 @@
 
     public IpManager(Context context, String ifName, Callback callback)
                 throws IllegalArgumentException {
-        super(TAG + "." + ifName);
+        super(IpManager.class.getSimpleName() + "." + ifName);
+        mTag = getName();
 
         mContext = context;
         mInterfaceName = ifName;
-
         mCallback = callback;
 
         mNwService = INetworkManagementService.Stub.asInterface(
@@ -171,7 +216,7 @@
         try {
             mNwService.registerObserver(mNetlinkTracker);
         } catch (RemoteException e) {
-            Log.e(TAG, "Couldn't register NetlinkTracker: " + e.toString());
+            Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
         }
 
         resetLinkProperties();
@@ -179,6 +224,8 @@
         // Super simple StateMachine.
         addState(mStoppedState);
         addState(mStartedState);
+        addState(mStoppingState);
+
         setInitialState(mStoppedState);
         setLogRecSize(MAX_LOG_RECORDS);
         super.start();
@@ -192,7 +239,9 @@
      */
     @VisibleForTesting
     protected IpManager(String ifName, Callback callback) {
-        super(TAG + ".test-" + ifName);
+        super(IpManager.class.getSimpleName() + ".test-" + ifName);
+        mTag = getName();
+
         mInterfaceName = ifName;
         mCallback = callback;
 
@@ -201,16 +250,35 @@
         mNetlinkTracker = null;
     }
 
-    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
-        getInterfaceIndex();
+    @Override
+    protected void onQuitting() {
+        mCallback.onQuit();
+    }
 
-        sendMessage(CMD_START, staticIpConfig);
+    // Shut down this IpManager instance altogether.
+    public void shutdown() {
+        stop();
+        quit();
+    }
+
+    public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() {
+        return new ProvisioningConfiguration.Builder();
+    }
+
+    public void startProvisioning(ProvisioningConfiguration req) {
+        getInterfaceIndex();
+        sendMessage(CMD_START, new ProvisioningConfiguration(req));
+    }
+
+    // TODO: Delete this.
+    public void startProvisioning(StaticIpConfiguration staticIpConfig) {
+        startProvisioning(buildProvisioningConfiguration()
+                .withStaticConfiguration(staticIpConfig)
+                .build());
     }
 
     public void startProvisioning() {
-        getInterfaceIndex();
-
-        sendMessage(CMD_START);
+        startProvisioning(new ProvisioningConfiguration());
     }
 
     public void stop() {
@@ -236,12 +304,48 @@
      * Internals.
      */
 
+    @Override
+    protected String getWhatToString(int what) {
+        // TODO: Investigate switching to reflection.
+        switch (what) {
+            case CMD_STOP:
+                return "CMD_STOP";
+            case CMD_START:
+                return "CMD_START";
+            case CMD_CONFIRM:
+                return "CMD_CONFIRM";
+            case EVENT_PRE_DHCP_ACTION_COMPLETE:
+                return "EVENT_PRE_DHCP_ACTION_COMPLETE";
+            case EVENT_NETLINK_LINKPROPERTIES_CHANGED:
+                return "EVENT_NETLINK_LINKPROPERTIES_CHANGED";
+            case DhcpClient.CMD_PRE_DHCP_ACTION:
+                return "DhcpClient.CMD_PRE_DHCP_ACTION";
+            case DhcpClient.CMD_POST_DHCP_ACTION:
+                return "DhcpClient.CMD_POST_DHCP_ACTION";
+            case DhcpClient.CMD_ON_QUIT:
+                return "DhcpClient.CMD_ON_QUIT";
+        }
+        return "UNKNOWN:" + Integer.toString(what);
+    }
+
+    @Override
+    protected String getLogRecString(Message msg) {
+        final String logLine = String.format(
+                "iface{%s/%d} arg1{%d} arg2{%d} obj{%s}",
+                mInterfaceName, mInterfaceIndex,
+                msg.arg1, msg.arg2, Objects.toString(msg.obj));
+        if (VDBG) {
+            Log.d(mTag, getWhatToString(msg.what) + " " + logLine);
+        }
+        return logLine;
+    }
+
     private void getInterfaceIndex() {
         try {
             mInterfaceIndex = NetworkInterface.getByName(mInterfaceName).getIndex();
         } catch (SocketException | NullPointerException e) {
             // TODO: throw new IllegalStateException.
-            Log.e(TAG, "ALERT: Failed to get interface index: ", e);
+            Log.e(mTag, "ALERT: Failed to get interface index: ", e);
         }
     }
 
@@ -252,7 +356,7 @@
     private void resetLinkProperties() {
         mNetlinkTracker.clearLinkProperties();
         mDhcpResults = null;
-        mStaticIpConfig = null;
+        mConfiguration = null;
 
         synchronized (mLock) {
             mLinkProperties = new LinkProperties();
@@ -260,16 +364,93 @@
         }
     }
 
+    // For now: use WifiStateMachine's historical notion of provisioned.
+    private static boolean isProvisioned(LinkProperties lp) {
+        // For historical reasons, we should connect even if all we have is
+        // an IPv4 address and nothing else.
+        return lp.isProvisioned() || lp.hasIPv4Address();
+    }
+
+    // TODO: Investigate folding all this into the existing static function
+    // LinkProperties.compareProvisioning() or some other single function that
+    // takes two LinkProperties objects and returns a ProvisioningChange
+    // object that is a correct and complete assessment of what changed, taking
+    // account of the asymmetries described in the comments in this function.
+    // Then switch to using it everywhere (IpReachabilityMonitor, etc.).
+    private static ProvisioningChange compareProvisioning(
+            LinkProperties oldLp, LinkProperties newLp) {
+        ProvisioningChange delta;
+
+        final boolean wasProvisioned = isProvisioned(oldLp);
+        final boolean isProvisioned = isProvisioned(newLp);
+
+        if (!wasProvisioned && isProvisioned) {
+            delta = ProvisioningChange.GAINED_PROVISIONING;
+        } else if (wasProvisioned && isProvisioned) {
+            delta = ProvisioningChange.STILL_PROVISIONED;
+        } else if (!wasProvisioned && !isProvisioned) {
+            delta = ProvisioningChange.STILL_NOT_PROVISIONED;
+        } else {
+            // (wasProvisioned && !isProvisioned)
+            //
+            // Note that this is true even if we lose a configuration element
+            // (e.g., a default gateway) that would not be required to advance
+            // into provisioned state. This is intended: if we have a default
+            // router and we lose it, that's a sure sign of a problem, but if
+            // we connect to a network with no IPv4 DNS servers, we consider
+            // that to be a network without DNS servers and connect anyway.
+            //
+            // See the comment below.
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        // Additionally:
+        //
+        // Partial configurations (e.g., only an IPv4 address with no DNS
+        // servers and no default route) are accepted as long as DHCPv4
+        // succeeds. On such a network, isProvisioned() will always return
+        // false, because the configuration is not complete, but we want to
+        // connect anyway. It might be a disconnected network such as a
+        // Chromecast or a wireless printer, for example.
+        //
+        // Because on such a network isProvisioned() will always return false,
+        // delta will never be LOST_PROVISIONING. So check for loss of
+        // provisioning here too.
+        if ((oldLp.hasIPv4Address() && !newLp.hasIPv4Address()) ||
+                (oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned())) {
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        return delta;
+    }
+
+    private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) {
+        switch (delta) {
+            case GAINED_PROVISIONING:
+                if (VDBG) { Log.d(mTag, "onProvisioningSuccess()"); }
+                mCallback.onProvisioningSuccess(newLp);
+                break;
+
+            case LOST_PROVISIONING:
+                if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
+                mCallback.onProvisioningFailure(newLp);
+                break;
+
+            default:
+                if (VDBG) { Log.d(mTag, "onLinkPropertiesChange()"); }
+                mCallback.onLinkPropertiesChange(newLp);
+                break;
+        }
+    }
+
     private ProvisioningChange setLinkProperties(LinkProperties newLp) {
         if (mIpReachabilityMonitor != null) {
             mIpReachabilityMonitor.updateLinkProperties(newLp);
         }
 
-        // TODO: Figure out whether and how to incorporate static configuration
-        // into the notion of provisioning.
         ProvisioningChange delta;
         synchronized (mLock) {
-            delta = LinkProperties.compareProvisioning(mLinkProperties, newLp);
+            delta = compareProvisioning(mLinkProperties, newLp);
             mLinkProperties = new LinkProperties(newLp);
         }
 
@@ -277,7 +458,7 @@
             switch (delta) {
                 case GAINED_PROVISIONING:
                 case LOST_PROVISIONING:
-                    Log.d(TAG, "provisioning: " + delta);
+                    Log.d(mTag, "provisioning: " + delta);
                     break;
             }
         }
@@ -333,7 +514,7 @@
         }
 
         if (VDBG) {
-            Log.d(TAG, "newLp{" + newLp + "}");
+            Log.d(mTag, "newLp{" + newLp + "}");
         }
 
         return newLp;
@@ -345,21 +526,51 @@
             ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
             mNwService.setInterfaceConfig(mInterfaceName, ifcg);
         } catch (RemoteException e) {
-            Log.e(TAG, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
+            Log.e(mTag, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
         }
     }
 
     private void handleIPv4Success(DhcpResults dhcpResults) {
         mDhcpResults = new DhcpResults(dhcpResults);
-        setLinkProperties(assembleLinkProperties());
-        mCallback.onIPv4ProvisioningSuccess(dhcpResults);
+        final LinkProperties newLp = assembleLinkProperties();
+        final ProvisioningChange delta = setLinkProperties(newLp);
+
+        if (VDBG) {
+            Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")");
+        }
+        mCallback.onNewDhcpResults(dhcpResults);
+
+        dispatchCallback(delta, newLp);
     }
 
     private void handleIPv4Failure() {
+        // TODO: Figure out to de-dup this and the same code in DhcpClient.
         clearIPv4Address();
         mDhcpResults = null;
-        setLinkProperties(assembleLinkProperties());
-        mCallback.onIPv4ProvisioningFailure();
+        final LinkProperties newLp = assembleLinkProperties();
+        ProvisioningChange delta = setLinkProperties(newLp);
+        // If we've gotten here and we're still not provisioned treat that as
+        // a total loss of provisioning.
+        //
+        // Either (a) static IP configuration failed or (b) DHCPv4 failed AND
+        // there was no usable IPv6 obtained before the DHCPv4 timeout.
+        //
+        // Regardless: GAME OVER.
+        //
+        // TODO: Make the DHCP client not time out and just continue in
+        // exponential backoff. Callers such as Wi-Fi which need a timeout
+        // should implement it themselves.
+        if (delta == ProvisioningChange.STILL_NOT_PROVISIONED) {
+            delta = ProvisioningChange.LOST_PROVISIONING;
+        }
+
+        if (VDBG) { Log.d(mTag, "onNewDhcpResults(null)"); }
+        mCallback.onNewDhcpResults(null);
+
+        dispatchCallback(delta, newLp);
+        if (delta == ProvisioningChange.LOST_PROVISIONING) {
+            transitionTo(mStoppingState);
+        }
     }
 
     class StoppedState extends State {
@@ -369,7 +580,7 @@
                 mNwService.disableIpv6(mInterfaceName);
                 mNwService.clearInterfaceAddresses(mInterfaceName);
             } catch (Exception e) {
-                Log.e(TAG, "Failed to clear addresses or disable IPv6" + e);
+                Log.e(mTag, "Failed to clear addresses or disable IPv6" + e);
             }
 
             resetLinkProperties();
@@ -382,7 +593,7 @@
                     break;
 
                 case CMD_START:
-                    mStaticIpConfig = (StaticIpConfiguration) msg.obj;
+                    mConfiguration = (ProvisioningConfiguration) msg.obj;
                     transitionTo(mStartedState);
                     break;
 
@@ -390,14 +601,9 @@
                     setLinkProperties(assembleLinkProperties());
                     break;
 
-                case DhcpStateMachine.CMD_ON_QUIT:
-                    // CMD_ON_QUIT is really more like "EVENT_ON_QUIT".
-                    // Shutting down DHCPv4 progresses simultaneously with
-                    // transitioning to StoppedState, so we can receive this
-                    // message after we've already transitioned here.
-                    //
-                    // TODO: Figure out if this is actually useful and if not
-                    // expunge it.
+                case DhcpClient.CMD_ON_QUIT:
+                    // Everything is already stopped.
+                    Log.e(mTag, "Unexpected CMD_ON_QUIT (already stopped).");
                     break;
 
                 default:
@@ -407,6 +613,30 @@
         }
     }
 
+    class StoppingState extends State {
+        @Override
+        public void enter() {
+            if (mDhcpClient == null) {
+                // There's no DHCPv4 for which to wait; proceed to stopped.
+                transitionTo(mStoppedState);
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message msg) {
+            switch (msg.what) {
+                case DhcpClient.CMD_ON_QUIT:
+                    mDhcpClient = null;
+                    transitionTo(mStoppedState);
+                    break;
+
+                default:
+                    deferMessage(msg);
+            }
+            return HANDLED;
+        }
+    }
+
     class StartedState extends State {
         @Override
         public void enter() {
@@ -416,48 +646,54 @@
                 mNwService.enableIpv6(mInterfaceName);
                 // TODO: Perhaps clearIPv4Address() as well.
             } catch (RemoteException re) {
-                Log.e(TAG, "Unable to change interface settings: " + re);
+                Log.e(mTag, "Unable to change interface settings: " + re);
             } catch (IllegalStateException ie) {
-                Log.e(TAG, "Unable to change interface settings: " + ie);
+                Log.e(mTag, "Unable to change interface settings: " + ie);
             }
 
-            mIpReachabilityMonitor = new IpReachabilityMonitor(
-                    mContext,
-                    mInterfaceName,
-                    new IpReachabilityMonitor.Callback() {
-                        @Override
-                        public void notifyLost(InetAddress ip, String logMsg) {
-                            if (mCallback.usingIpReachabilityMonitor()) {
+            if (mConfiguration.mUsingIpReachabilityMonitor) {
+                mIpReachabilityMonitor = new IpReachabilityMonitor(
+                        mContext,
+                        mInterfaceName,
+                        new IpReachabilityMonitor.Callback() {
+                            @Override
+                            public void notifyLost(InetAddress ip, String logMsg) {
                                 mCallback.onReachabilityLost(logMsg);
                             }
-                        }
-                    });
+                        });
+            }
 
             // If we have a StaticIpConfiguration attempt to apply it and
             // handle the result accordingly.
-            if (mStaticIpConfig != null) {
+            if (mConfiguration.mStaticIpConfig != null) {
                 if (applyStaticIpConfig()) {
-                    handleIPv4Success(new DhcpResults(mStaticIpConfig));
+                    handleIPv4Success(new DhcpResults(mConfiguration.mStaticIpConfig));
                 } else {
-                    handleIPv4Failure();
+                    if (VDBG) { Log.d(mTag, "onProvisioningFailure()"); }
+                    mCallback.onProvisioningFailure(getLinkProperties());
+                    transitionTo(mStoppingState);
                 }
             } else {
                 // Start DHCPv4.
-                makeDhcpStateMachine();
-                mDhcpStateMachine.registerForPreDhcpNotification();
-                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
+                mDhcpClient = DhcpClient.makeDhcpClient(
+                        mContext,
+                        IpManager.this,
+                        mInterfaceName);
+                mDhcpClient.registerForPreDhcpNotification();
+                mDhcpClient.sendMessage(DhcpClient.CMD_START_DHCP);
             }
         }
 
         @Override
         public void exit() {
-            mIpReachabilityMonitor.stop();
-            mIpReachabilityMonitor = null;
+            if (mIpReachabilityMonitor != null) {
+                mIpReachabilityMonitor.stop();
+                mIpReachabilityMonitor = null;
+            }
 
-            if (mDhcpStateMachine != null) {
-                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-                mDhcpStateMachine.doQuit();
-                mDhcpStateMachine = null;
+            if (mDhcpClient != null) {
+                mDhcpClient.sendMessage(DhcpClient.CMD_STOP_DHCP);
+                mDhcpClient.doQuit();
             }
 
             resetLinkProperties();
@@ -471,7 +707,7 @@
                     break;
 
                 case CMD_START:
-                    Log.e(TAG, "ALERT: START received in StartedState. Please fix caller.");
+                    Log.e(mTag, "ALERT: START received in StartedState. Please fix caller.");
                     break;
 
                 case CMD_CONFIRM:
@@ -479,7 +715,7 @@
                     // that both probes (a) on-link neighbors and (b) does
                     // a DHCPv4 RENEW.  We used to do this on Wi-Fi framework
                     // roams.
-                    if (mCallback.usingIpReachabilityMonitor()) {
+                    if (mIpReachabilityMonitor != null) {
                         mIpReachabilityMonitor.probeAll();
                     }
                     break;
@@ -488,9 +724,8 @@
                     // It's possible to reach here if, for example, someone
                     // calls completedPreDhcpAction() after provisioning with
                     // a static IP configuration.
-                    if (mDhcpStateMachine != null) {
-                        mDhcpStateMachine.sendMessage(
-                                DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
+                    if (mDhcpClient != null) {
+                        mDhcpClient.sendMessage(DhcpClient.CMD_PRE_DHCP_ACTION_COMPLETE);
                     }
                     break;
 
@@ -500,57 +735,47 @@
                         break;
                     }
                     final ProvisioningChange delta = setLinkProperties(newLp);
-
-                    // NOTE: The only receiver of these callbacks currently
-                    // treats all three of them identically, namely it calls
-                    // IpManager#getLinkProperties() and makes its own determination.
-                    switch (delta) {
-                        case GAINED_PROVISIONING:
-                            mCallback.onProvisioningSuccess(newLp);
-                            break;
-
-                        case LOST_PROVISIONING:
-                            mCallback.onProvisioningFailure(newLp);
-                            break;
-
-                        default:
-                            // TODO: Only notify on STILL_PROVISIONED?
-                            mCallback.onLinkPropertiesChange(newLp);
-                            break;
+                    dispatchCallback(delta, newLp);
+                    if (delta == ProvisioningChange.LOST_PROVISIONING) {
+                        transitionTo(mStoppedState);
                     }
                     break;
                 }
 
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                    mCallback.onPreDhcpAction();
+                case DhcpClient.CMD_PRE_DHCP_ACTION:
+                    if (VDBG) { Log.d(mTag, "onPreDhcpAction()"); }
+                    if (mConfiguration.mRequestedPreDhcpAction) {
+                        mCallback.onPreDhcpAction();
+                    } else {
+                        sendMessage(EVENT_PRE_DHCP_ACTION_COMPLETE);
+                    }
                     break;
 
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION: {
+                case DhcpClient.CMD_POST_DHCP_ACTION: {
                     // Note that onPostDhcpAction() is likely to be
                     // asynchronous, and thus there is no guarantee that we
                     // will be able to observe any of its effects here.
+                    if (VDBG) { Log.d(mTag, "onPostDhcpAction()"); }
                     mCallback.onPostDhcpAction();
 
                     final DhcpResults dhcpResults = (DhcpResults) msg.obj;
                     switch (msg.arg1) {
-                        case DhcpStateMachine.DHCP_SUCCESS:
+                        case DhcpClient.DHCP_SUCCESS:
                             handleIPv4Success(dhcpResults);
                             break;
-                        case DhcpStateMachine.DHCP_FAILURE:
+                        case DhcpClient.DHCP_FAILURE:
                             handleIPv4Failure();
                             break;
                         default:
-                            Log.e(TAG, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
+                            Log.e(mTag, "Unknown CMD_POST_DHCP_ACTION status:" + msg.arg1);
                     }
                     break;
                 }
 
-                case DhcpStateMachine.CMD_ON_QUIT:
-                    // CMD_ON_QUIT is really more like "EVENT_ON_QUIT".
-                    // Regardless, we ignore it.
-                    //
-                    // TODO: Figure out if this is actually useful and if not
-                    // expunge it.
+                case DhcpClient.CMD_ON_QUIT:
+                    // DHCPv4 quit early for some reason.
+                    Log.e(mTag, "Unexpected CMD_ON_QUIT.");
+                    mDhcpClient = null;
                     break;
 
                 default:
@@ -561,35 +786,17 @@
 
         private boolean applyStaticIpConfig() {
             final InterfaceConfiguration ifcg = new InterfaceConfiguration();
-            ifcg.setLinkAddress(mStaticIpConfig.ipAddress);
+            ifcg.setLinkAddress(mConfiguration.mStaticIpConfig.ipAddress);
             ifcg.setInterfaceUp();
             try {
                 mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-                if (DBG) Log.d(TAG, "Static IP configuration succeeded");
+                if (DBG) Log.d(mTag, "Static IP configuration succeeded");
             } catch (IllegalStateException | RemoteException e) {
-                Log.e(TAG, "Static IP configuration failed: ", e);
+                Log.e(mTag, "Static IP configuration failed: ", e);
                 return false;
             }
 
             return true;
         }
-
-        private void makeDhcpStateMachine() {
-            final boolean usingLegacyDhcp = (Settings.Global.getInt(
-                    mContext.getContentResolver(),
-                    Settings.Global.LEGACY_DHCP_CLIENT, 0) == 1);
-
-            if (usingLegacyDhcp) {
-                mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
-                        mContext,
-                        IpManager.this,
-                        mInterfaceName);
-            } else {
-                mDhcpStateMachine = DhcpClient.makeDhcpStateMachine(
-                        mContext,
-                        IpManager.this,
-                        mInterfaceName);
-            }
-        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
index 313dc8b..e45b92a 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -145,14 +145,10 @@
                 "provider", 0);
         Bundle extras = new Bundle();
         SyncOperation periodic = new SyncOperation(ep, 0, "package", 0, 0, extras, false, true,
-                SyncOperation.NO_JOB_ID);
-        periodic.periodMillis = 60000;
-        periodic.flexMillis = 10000;
+                SyncOperation.NO_JOB_ID, 60000, 10000);
         SyncOperation oneoff = periodic.createOneTimeSyncOperation();
         assertFalse("Conversion to oneoff sync failed.", oneoff.isPeriodic);
-        SyncOperation recreated = oneoff.createPeriodicSyncOperation();
-        assertTrue("Conversion to periodic sync failed.", oneoff.isPeriodic);
-        assertEquals("Period not restored", periodic.periodMillis, recreated.periodMillis);
-        assertEquals("Flex not restored", periodic.flexMillis, recreated.flexMillis);
+        assertEquals("Period not restored", periodic.periodMillis, oneoff.periodMillis);
+        assertEquals("Flex not restored", periodic.flexMillis, oneoff.flexMillis);
     }
 }
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 64f60d93..b23ad50 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -22,9 +22,12 @@
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.net.wifi.WifiInfo;
 import android.os.Build.VERSION_CODES;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
 import android.os.UserHandle;
@@ -43,7 +46,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -91,6 +93,9 @@
         when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                 .thenReturn(true);
 
+        // By default, pretend all users are running and unlocked.
+        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
+
         initializeDpms();
 
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
@@ -412,6 +417,45 @@
     }
 
     /**
+     * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
+     * (because we can't send the remove broadcast).
+     */
+    public void testRemoveActiveAdmin_userNotRunningOrLocked() {
+        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+
+        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
+
+        // Add admin.
+
+        dpm.setActiveAdmin(admin1, /* replace =*/ false);
+
+        assertTrue(dpm.isAdminActive(admin1));
+
+        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+
+        // 1. User not unlocked.
+        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+                .thenReturn(false);
+        try {
+            dpm.removeActiveAdmin(admin1);
+            fail("Didn't throw IllegalStateException");
+        } catch (IllegalStateException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "User must be running and unlocked", expected.getMessage());
+        }
+
+        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+
+        // 2. User unlocked.
+        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
+                .thenReturn(true);
+
+        dpm.removeActiveAdmin(admin1);
+
+        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
+    }
+
+    /**
      * Test for:
      * {@link DevicePolicyManager#removeActiveAdmin}
      */
@@ -779,6 +823,18 @@
         doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
                 eq(admin1.getPackageName()),
                 anyInt());
+
+        // But first pretend the user is locked.  Then it should fail.
+        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
+        try {
+            dpm.clearDeviceOwnerApp(admin1.getPackageName());
+            fail("Didn't throw IllegalStateException");
+        } catch (IllegalStateException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "User must be running and unlocked", expected.getMessage());
+        }
+
+        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
         reset(mContext.userManagerInternal);
         dpm.clearDeviceOwnerApp(admin1.getPackageName());
 
@@ -866,7 +922,19 @@
         assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
         assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
 
-        // Clear
+        // First try when the user is locked, which should fail.
+        when(mContext.userManager.isUserUnlocked(anyInt()))
+                .thenReturn(false);
+        try {
+            dpm.clearProfileOwner(admin1);
+            fail("Didn't throw IllegalStateException");
+        } catch (IllegalStateException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "User must be running and unlocked", expected.getMessage());
+        }
+        // Clear, really.
+        when(mContext.userManager.isUserUnlocked(anyInt()))
+                .thenReturn(true);
         dpm.clearProfileOwner(admin1);
 
         // Check
@@ -995,6 +1063,7 @@
     public void testApplicationRestrictionsManagingApp() throws Exception {
         setAsProfileOwner(admin1);
 
+        final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
         final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
         final int appRestrictionsManagerAppId = 20987;
         final int appRestrictionsManagerUid = UserHandle.getUid(
@@ -1004,6 +1073,14 @@
                 eq(DpmMockContext.CALLER_USER_HANDLE));
         mContext.binder.callingUid = appRestrictionsManagerUid;
 
+        final PackageInfo pi = new PackageInfo();
+        pi.applicationInfo = new ApplicationInfo();
+        pi.applicationInfo.flags = ApplicationInfo.FLAG_HAS_CODE;
+        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
+                eq(appRestrictionsManagerPackage),
+                anyInt(),
+                eq(DpmMockContext.CALLER_USER_HANDLE));
+
         // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't
         // delegated that permission yet.
         assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
@@ -1028,6 +1105,16 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_UID;
         assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
 
+        // Check the API does not allow setting a non-existent package
+        try {
+            dpm.setApplicationRestrictionsManagingPackage(admin1,
+                    nonExistAppRestrictionsManagerPackage);
+            fail("Non-existent app set as app restriction manager.");
+        } catch (IllegalArgumentException expected) {
+            MoreAsserts.assertContainsRegex(
+                    "is not installed on the current user", expected.getMessage());
+        }
+
         // Let appRestrictionsManagerPackage manage app restrictions
         dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
         assertEquals(appRestrictionsManagerPackage,
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index ae0a25e..577c3a1 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -58,7 +58,7 @@
                 .setMinimumLatency(runFromMillis)
                 .setPersisted(true)
                 .build();
-        final JobStatus ts = new JobStatus(task, SOME_UID);
+        final JobStatus ts = new JobStatus(task, SOME_UID, null, -1);
         mTaskStoreUnderTest.add(ts);
         Thread.sleep(IO_WAIT);
         // Manually load tasks from xml file.
@@ -91,8 +91,8 @@
                 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
                 .setPersisted(true)
                 .build();
-        final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID);
-        final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID);
+        final JobStatus taskStatus1 = new JobStatus(task1, SOME_UID, null, -1);
+        final JobStatus taskStatus2 = new JobStatus(task2, SOME_UID, null, -1);
         mTaskStoreUnderTest.add(taskStatus1);
         mTaskStoreUnderTest.add(taskStatus2);
         Thread.sleep(IO_WAIT);
@@ -140,7 +140,7 @@
         extras.putInt("into", 3);
         b.setExtras(extras);
         final JobInfo task = b.build();
-        JobStatus taskStatus = new JobStatus(task, SOME_UID);
+        JobStatus taskStatus = new JobStatus(task, SOME_UID, null, -1);
 
         mTaskStoreUnderTest.add(taskStatus);
         Thread.sleep(IO_WAIT);
@@ -151,17 +151,59 @@
         JobStatus loaded = jobStatusSet.iterator().next();
         assertTasksEqual(task, loaded.getJob());
     }
+    public void testWritingTaskWithSourcePackage() throws Exception {
+        JobInfo.Builder b = new Builder(8, mComponent)
+                .setRequiresDeviceIdle(true)
+                .setPeriodic(10000L)
+                .setRequiresCharging(true)
+                .setPersisted(true);
+        JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, "com.google.android.gms", 0);
+
+        mTaskStoreUnderTest.add(taskStatus);
+        Thread.sleep(IO_WAIT);
+
+        final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
+        mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+        assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+        JobStatus loaded = jobStatusSet.iterator().next();
+        assertEquals("Source package not equal.", loaded.getSourcePackageName(),
+                taskStatus.getSourcePackageName());
+        assertEquals("Source user not equal.", loaded.getSourceUserId(),
+                taskStatus.getSourceUserId());
+    }
+
+    public void testWritingTaskWithFlex() throws Exception {
+        JobInfo.Builder b = new Builder(8, mComponent)
+                .setRequiresDeviceIdle(true)
+                .setPeriodic(5*60*60*1000, 1*60*60*1000)
+                .setRequiresCharging(true)
+                .setPersisted(true);
+        JobStatus taskStatus = new JobStatus(b.build(), SOME_UID, null, -1);
+
+        mTaskStoreUnderTest.add(taskStatus);
+        Thread.sleep(IO_WAIT);
+
+        final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
+        mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet);
+        assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+        JobStatus loaded = jobStatusSet.iterator().next();
+        assertEquals("Period not equal.", loaded.getJob().getIntervalMillis(),
+                taskStatus.getJob().getIntervalMillis());
+        assertEquals("Flex not equal.", loaded.getJob().getFlexMillis(),
+                taskStatus.getJob().getFlexMillis());
+    }
 
     public void testMassivePeriodClampedOnRead() throws Exception {
-        final long TEN_SECONDS = 10000L;
+        final long ONE_HOUR = 60*60*1000L; // flex
+        final long TWO_HOURS = 2 * ONE_HOUR; // period
         JobInfo.Builder b = new Builder(8, mComponent)
-                .setPeriodic(TEN_SECONDS)
+                .setPeriodic(TWO_HOURS, ONE_HOUR)
                 .setPersisted(true);
         final long invalidLateRuntimeElapsedMillis =
-                SystemClock.elapsedRealtime() + (TEN_SECONDS * 2) + 5000;  // >2P from now.
+                SystemClock.elapsedRealtime() + (TWO_HOURS * ONE_HOUR) + TWO_HOURS;  // > period+flex
         final long invalidEarlyRuntimeElapsedMillis =
-                invalidLateRuntimeElapsedMillis - TEN_SECONDS;  // Early is (late - period).
-        final JobStatus js = new JobStatus(b.build(), SOME_UID,
+                invalidLateRuntimeElapsedMillis - TWO_HOURS;  // Early is (late - period).
+        final JobStatus js = new JobStatus(b.build(), SOME_UID, "somePackage", 0 /* sourceUserId */,
                 invalidEarlyRuntimeElapsedMillis, invalidLateRuntimeElapsedMillis);
 
         mTaskStoreUnderTest.add(js);
@@ -176,10 +218,10 @@
         // call SystemClock.elapsedRealtime after doing the disk i/o.
         final long newNowElapsed = SystemClock.elapsedRealtime();
         assertTrue("Early runtime wasn't correctly clamped.",
-                loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS);
-        // Assert late runtime was clamped to be now + period*2.
+                loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS);
+        // Assert late runtime was clamped to be now + period + flex.
         assertTrue("Early runtime wasn't correctly clamped.",
-                loaded.getEarliestRunTime() <= newNowElapsed + TEN_SECONDS * 2);
+                loaded.getEarliestRunTime() <= newNowElapsed + TWO_HOURS + ONE_HOUR);
     }
 
     public void testPriorityPersisted() throws Exception {
@@ -187,7 +229,7 @@
                 .setOverrideDeadline(5000)
                 .setPriority(42)
                 .setPersisted(true);
-        final JobStatus js = new JobStatus(b.build(), SOME_UID);
+        final JobStatus js = new JobStatus(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(js);
         Thread.sleep(IO_WAIT);
         final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
@@ -203,12 +245,12 @@
         JobInfo.Builder b = new Builder(42, mComponent)
                 .setOverrideDeadline(10000)
                 .setPersisted(false);
-        JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID);
+        JobStatus jsNonPersisted = new JobStatus(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(jsNonPersisted);
         b = new Builder(43, mComponent)
                 .setOverrideDeadline(10000)
                 .setPersisted(true);
-        JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID);
+        JobStatus jsPersisted = new JobStatus(b.build(), SOME_UID, null, -1);
         mTaskStoreUnderTest.add(jsPersisted);
         Thread.sleep(IO_WAIT);
         final ArraySet<JobStatus> jobStatusSet = new ArraySet<JobStatus>();
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
index 7f9a0de..ba83be1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -39,7 +39,7 @@
     public PackageSetting generateFakePackageSetting(String name) {
         return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
                 new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
-                "", 1, 0, 0);
+                "", 1, 0, 0, null, null);
     }
 
     @Override
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 46ad8a1..acc752a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -74,6 +74,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.SystemService;
 
@@ -125,6 +126,7 @@
     Handler mHandler;
     AppOpsManager mAppOps;
     UserManager mUserManager;
+    PackageManager mPackageManager;
     AppWidgetManager mAppWidgetManager;
     IDeviceIdleController mDeviceIdleController;
     private DisplayManager mDisplayManager;
@@ -157,7 +159,7 @@
     public void onStart() {
         mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-
+        mPackageManager = getContext().getPackageManager();
         mHandler = new H(BackgroundThread.get().getLooper());
 
         File systemDataDir = new File(Environment.getDataDirectory(), "system");
@@ -296,9 +298,8 @@
     private void initializeDefaultsForSystemApps(int userId) {
         Slog.d(TAG, "Initializing defaults for system apps on user " + userId);
         final long elapsedRealtime = SystemClock.elapsedRealtime();
-        List<PackageInfo> packages = getContext().getPackageManager().getInstalledPackagesAsUser(
-                PackageManager.MATCH_DISABLED_COMPONENTS
-                | PackageManager.MATCH_UNINSTALLED_PACKAGES,
+        List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
+                PackageManager.MATCH_DISABLED_COMPONENTS,
                 userId);
         final int packageCount = packages.size();
         for (int i = 0; i < packageCount; i++) {
@@ -398,31 +399,38 @@
         }
     }
 
-    /** Check all running users' or specified user's apps to see if they enter an idle state. */
-    void checkIdleStates(int checkUserId) {
+    /**
+     * Check all running users' or specified user's apps to see if they enter an idle state.
+     * @return Returns whether checking should continue periodically.
+     */
+    boolean checkIdleStates(int checkUserId) {
         if (!mAppIdleEnabled) {
-            return;
+            return false;
         }
 
-        final int[] userIds;
+        final int[] runningUserIds;
         try {
-            if (checkUserId == UserHandle.USER_ALL) {
-                userIds = ActivityManagerNative.getDefault().getRunningUserIds();
-            } else {
-                userIds = new int[] { checkUserId };
+            runningUserIds = ActivityManagerNative.getDefault().getRunningUserIds();
+            if (checkUserId != UserHandle.USER_ALL
+                    && !ArrayUtils.contains(runningUserIds, checkUserId)) {
+                return false;
             }
         } catch (RemoteException re) {
-            return;
+            return false;
         }
 
         final long elapsedRealtime = SystemClock.elapsedRealtime();
-        for (int i = 0; i < userIds.length; i++) {
-            final int userId = userIds[i];
-            List<PackageInfo> packages =
-                    getContext().getPackageManager().getInstalledPackagesAsUser(
-                            PackageManager.MATCH_DISABLED_COMPONENTS
-                                | PackageManager.MATCH_UNINSTALLED_PACKAGES,
-                            userId);
+        for (int i = 0; i < runningUserIds.length; i++) {
+            final int userId = runningUserIds[i];
+            if (checkUserId != UserHandle.USER_ALL && checkUserId != userId) {
+                continue;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "Checking idle state for user " + userId);
+            }
+            List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
+                    PackageManager.MATCH_DISABLED_COMPONENTS,
+                    userId);
             synchronized (mLock) {
                 final int packageCount = packages.size();
                 for (int p = 0; p < packageCount; p++) {
@@ -439,6 +447,11 @@
                 }
             }
         }
+        if (DEBUG) {
+            Slog.d(TAG, "checkIdleStates took "
+                    + (SystemClock.elapsedRealtime() - elapsedRealtime));
+        }
+        return true;
     }
 
     /** Check if it's been a while since last parole and let idle apps do some work */
@@ -459,7 +472,7 @@
 
     private void notifyBatteryStats(String packageName, int userId, boolean idle) {
         try {
-            final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
+            final int uid = mPackageManager.getPackageUidAsUser(packageName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
             if (idle) {
                 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE,
@@ -468,7 +481,7 @@
                 mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE,
                         packageName, uid);
             }
-        } catch (RemoteException re) {
+        } catch (NameNotFoundException | RemoteException e) {
         }
     }
 
@@ -592,7 +605,7 @@
             // Only force the sync adapters to active if the provider is not in the same package and
             // the sync adapter is a system package.
             try {
-                PackageInfo pi = AppGlobals.getPackageManager().getPackageInfo(
+                PackageInfo pi = mPackageManager.getPackageInfoAsUser(
                         packageName, PackageManager.MATCH_SYSTEM_ONLY, userId);
                 if (pi == null || pi.applicationInfo == null) {
                     continue;
@@ -600,7 +613,7 @@
                 if (!packageName.equals(providerPkgName)) {
                     forceIdleState(packageName, userId, false);
                 }
-            } catch (RemoteException re) {
+            } catch (NameNotFoundException e) {
                 // Shouldn't happen
             }
         }
@@ -725,7 +738,7 @@
 
     int getAppId(String packageName) {
         try {
-            ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(packageName,
+            ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES
                             | PackageManager.MATCH_DISABLED_COMPONENTS);
             return ai.uid;
@@ -772,12 +785,8 @@
             }
         } catch (RemoteException re) {
         }
-        // TODO: Optimize this check
-        if (isActiveDeviceAdmin(packageName, userId)) {
-            return false;
-        }
 
-        if (isCarrierApp(packageName)) {
+        if (isActiveDeviceAdmin(packageName, userId)) {
             return false;
         }
 
@@ -790,7 +799,17 @@
             return false;
         }
 
-        return isAppIdleUnfiltered(packageName, userId, elapsedRealtime);
+        if (!isAppIdleUnfiltered(packageName, userId, elapsedRealtime)) {
+            return false;
+        }
+
+        // Check this last, as it is the most expensive check
+        // TODO: Optimize this by fetching the carrier privileged apps ahead of time
+        if (isCarrierApp(packageName)) {
+            return false;
+        }
+
+        return true;
     }
 
     int[] getIdleUidsForUser(int userId) {
@@ -803,7 +822,7 @@
         List<ApplicationInfo> apps;
         try {
             ParceledListSlice<ApplicationInfo> slice = AppGlobals.getPackageManager()
-                    .getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+                    .getInstalledApplications(/* flags= */ 0, userId);
             if (slice == null) {
                 return new int[0];
             }
@@ -833,7 +852,9 @@
                 uidStates.setValueAt(index, value + 1 + (idle ? 1<<16 : 0));
             }
         }
-
+        if (DEBUG) {
+            Slog.d(TAG, "getIdleUids took " + (SystemClock.elapsedRealtime() - elapsedRealtime));
+        }
         int numIdle = 0;
         for (int i = uidStates.size() - 1; i >= 0; i--) {
             int value = uidStates.valueAt(i);
@@ -865,15 +886,7 @@
     private boolean isActiveDeviceAdmin(String packageName, int userId) {
         DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
         if (dpm == null) return false;
-        List<ComponentName> components = dpm.getActiveAdminsAsUser(userId);
-        if (components == null) return false;
-        final int size = components.size();
-        for (int i = 0; i < size; i++) {
-            if (components.get(i).getPackageName().equals(packageName)) {
-                return true;
-            }
-        }
-        return false;
+        return dpm.packageHasActiveAdmins(packageName, userId);
     }
 
     private boolean isCarrierApp(String packageName) {
@@ -1011,10 +1024,11 @@
                     break;
 
                 case MSG_CHECK_IDLE_STATES:
-                    checkIdleStates(msg.arg1);
-                    mHandler.sendMessageDelayed(mHandler.obtainMessage(
-                            MSG_CHECK_IDLE_STATES, msg.arg1, 0),
-                            mCheckIdleIntervalMillis);
+                    if (checkIdleStates(msg.arg1)) {
+                        mHandler.sendMessageDelayed(mHandler.obtainMessage(
+                                MSG_CHECK_IDLE_STATES, msg.arg1, 0),
+                                mCheckIdleIntervalMillis);
+                    }
                     break;
 
                 case MSG_ONE_TIME_CHECK_IDLE_STATES:
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
index 18a5d59..f7cd6a3 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerDbHelper.java
@@ -54,6 +54,7 @@
     private static final String CREATE_TABLE_ST_SOUND_MODEL = "CREATE TABLE "
             + GenericSoundModelContract.TABLE + "("
             + GenericSoundModelContract.KEY_MODEL_UUID + " TEXT PRIMARY KEY,"
+            + GenericSoundModelContract.KEY_VENDOR_UUID + " TEXT,"
             + GenericSoundModelContract.KEY_DATA + " BLOB" + " )";
 
 
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 354075e..cde47bd 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -16,12 +16,16 @@
 
 package com.android.server.soundtrigger;
 
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.soundtrigger.IRecognitionStatusCallback;
 import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericRecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
 import android.hardware.soundtrigger.SoundTrigger.Keyphrase;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionEvent;
 import android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra;
@@ -29,6 +33,7 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionEvent;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
 import android.hardware.soundtrigger.SoundTrigger.SoundModelEvent;
 import android.hardware.soundtrigger.SoundTriggerModule;
 import android.os.PowerManager;
@@ -40,9 +45,16 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.UUID;
 
 /**
- * Helper for {@link SoundTrigger} APIs.
+ * Helper for {@link SoundTrigger} APIs. Supports two types of models:
+ * (i) A voice model which is exported via the {@link VoiceInteractionService}. There can only be
+ * a single voice model running on the DSP at any given time.
+ *
+ * (ii) Generic sound-trigger models: Supports multiple of these.
+ *
  * Currently this just acts as an abstraction over all SoundTrigger API calls.
  *
  * @hide
@@ -62,7 +74,7 @@
     private static final int INVALID_VALUE = Integer.MIN_VALUE;
 
     /** The {@link ModuleProperties} for the system, or null if none exists. */
-    final ModuleProperties moduleProperties;
+    final ModuleProperties mModuleProperties;
 
     /** The properties for the DSP module */
     private SoundTriggerModule mModule;
@@ -72,21 +84,36 @@
     private final PhoneStateListener mPhoneStateListener;
     private final PowerManager mPowerManager;
 
-    // TODO: Since many layers currently only deal with one recognition
+    // TODO: Since the voice layer currently only handles one recognition
     // we simplify things by assuming one listener here too.
-    private IRecognitionStatusCallback mActiveListener;
+    private IRecognitionStatusCallback mKeyphraseListener;
+
+    // The SoundTriggerManager layer handles multiple generic recognition models. We store the
+    // ModelData here in a hashmap.
+    private final HashMap<UUID, ModelData> mGenericModelDataMap;
+
+    // Note: KeyphraseId is not really used.
     private int mKeyphraseId = INVALID_VALUE;
-    private int mCurrentSoundModelHandle = INVALID_VALUE;
+
+    // Current voice sound model handle. We only allow one voice model to run at any given time.
+    private int mCurrentKeyphraseModelHandle = INVALID_VALUE;
     private KeyphraseSoundModel mCurrentSoundModel = null;
     // FIXME: Ideally this should not be stored if allowMultipleTriggers happens at a lower layer.
     private RecognitionConfig mRecognitionConfig = null;
+
+    // Whether we are requesting recognition to start.
     private boolean mRequested = false;
     private boolean mCallActive = false;
     private boolean mIsPowerSaveMode = false;
     // Indicates if the native sound trigger service is disabled or not.
     // This is an indirect indication of the microphone being open in some other application.
     private boolean mServiceDisabled = false;
-    private boolean mStarted = false;
+
+    // Whether we have ANY recognition (keyphrase or generic) running.
+    private boolean mRecognitionRunning = false;
+
+    // Keeps track of whether the keyphrase recognition is running.
+    private boolean mKeyphraseStarted = false;
     private boolean mRecognitionAborted = false;
     private PowerSaveModeListener mPowerSaveModeListener;
 
@@ -96,14 +123,87 @@
         mContext = context;
         mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mGenericModelDataMap = new HashMap<UUID, ModelData>();
         mPhoneStateListener = new MyCallStateListener();
         if (status != SoundTrigger.STATUS_OK || modules.size() == 0) {
             Slog.w(TAG, "listModules status=" + status + ", # of modules=" + modules.size());
-            moduleProperties = null;
+            mModuleProperties = null;
             mModule = null;
         } else {
             // TODO: Figure out how to determine which module corresponds to the DSP hardware.
-            moduleProperties = modules.get(0);
+            mModuleProperties = modules.get(0);
+        }
+    }
+
+    /**
+     * Starts recognition for the given generic sound model ID.
+     *
+     * @param soundModel The sound model to use for recognition.
+     * @param listener The listener for the recognition events related to the given keyphrase.
+     * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+     */
+    int startGenericRecognition(UUID modelId, GenericSoundModel soundModel,
+            IRecognitionStatusCallback callback, RecognitionConfig recognitionConfig) {
+        if (soundModel == null || callback == null || recognitionConfig == null) {
+            Slog.w(TAG, "Passed in bad data to startGenericRecognition().");
+            return STATUS_ERROR;
+        }
+
+        synchronized (mLock) {
+
+            if (mModuleProperties == null) {
+                Slog.w(TAG, "Attempting startRecognition without the capability");
+                return STATUS_ERROR;
+            }
+
+            if (mModule == null) {
+                mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null);
+                if (mModule == null) {
+                    Slog.w(TAG, "startRecognition cannot attach to sound trigger module");
+                    return STATUS_ERROR;
+                }
+            }
+
+            // Initialize power save, call active state monitoring logic.
+            if (!mRecognitionRunning) {
+                initializeTelephonyAndPowerStateListeners();
+            }
+
+            // Fetch a ModelData instance from the hash map. Creates a new one if none
+            // exists.
+            ModelData modelData = getOrCreateGenericModelData(modelId);
+
+            IRecognitionStatusCallback oldCallback = modelData.getCallback();
+            if (oldCallback != null) {
+                Slog.w(TAG, "Canceling previous recognition for model id: " + modelId);
+                try {
+                    oldCallback.onError(STATUS_ERROR);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onDetectionStopped", e);
+                }
+                modelData.clearCallback();
+            }
+
+            // Load the model if its not loaded.
+            if (!modelData.isModelLoaded()) {
+                // Load the model
+                int[] handle = new int[] { INVALID_VALUE };
+                int status = mModule.loadSoundModel(soundModel, handle);
+                if (status != SoundTrigger.STATUS_OK) {
+                    Slog.w(TAG, "loadSoundModel call failed with " + status);
+                    return status;
+                }
+                if (handle[0] == INVALID_VALUE) {
+                    Slog.w(TAG, "loadSoundModel call returned invalid sound model handle");
+                    return STATUS_ERROR;
+                }
+                modelData.setHandle(handle[0]);
+            }
+            modelData.setCallback(callback);
+            modelData.setRecognitionConfig(recognitionConfig);
+
+            // Don't notify for synchronous calls.
+            return startGenericRecognitionLocked(modelData, false);
         }
     }
 
@@ -116,7 +216,7 @@
      * @param listener The listener for the recognition events related to the given keyphrase.
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int startRecognition(int keyphraseId,
+    int startKeyphraseRecognition(int keyphraseId,
             KeyphraseSoundModel soundModel,
             IRecognitionStatusCallback listener,
             RecognitionConfig recognitionConfig) {
@@ -129,36 +229,24 @@
                 Slog.d(TAG, "startRecognition for keyphraseId=" + keyphraseId
                         + " soundModel=" + soundModel + ", listener=" + listener.asBinder()
                         + ", recognitionConfig=" + recognitionConfig);
-                Slog.d(TAG, "moduleProperties=" + moduleProperties);
+                Slog.d(TAG, "moduleProperties=" + mModuleProperties);
                 Slog.d(TAG, "current listener="
-                        + (mActiveListener == null ? "null" : mActiveListener.asBinder()));
-                Slog.d(TAG, "current SoundModel handle=" + mCurrentSoundModelHandle);
+                        + (mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder()));
+                Slog.d(TAG, "current SoundModel handle=" + mCurrentKeyphraseModelHandle);
                 Slog.d(TAG, "current SoundModel UUID="
                         + (mCurrentSoundModel == null ? null : mCurrentSoundModel.uuid));
             }
 
-            if (!mStarted) {
-                // Get the current call state synchronously for the first recognition.
-                mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
-                // Register for call state changes when the first call to start recognition occurs.
-                mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-                // Register for power saver mode changes when the first call to start recognition
-                // occurs.
-                if (mPowerSaveModeListener == null) {
-                    mPowerSaveModeListener = new PowerSaveModeListener();
-                    mContext.registerReceiver(mPowerSaveModeListener,
-                            new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
-                }
-                mIsPowerSaveMode = mPowerManager.isPowerSaveMode();
+            if (!mRecognitionRunning) {
+                initializeTelephonyAndPowerStateListeners();
             }
 
-            if (moduleProperties == null) {
+            if (mModuleProperties == null) {
                 Slog.w(TAG, "Attempting startRecognition without the capability");
                 return STATUS_ERROR;
             }
             if (mModule == null) {
-                mModule = SoundTrigger.attachModule(moduleProperties.id, this, null);
+                mModule = SoundTrigger.attachModule(mModuleProperties.id, this, null);
                 if (mModule == null) {
                     Slog.w(TAG, "startRecognition cannot attach to sound trigger module");
                     return STATUS_ERROR;
@@ -168,32 +256,32 @@
             // Unload the previous model if the current one isn't invalid
             // and, it's not the same as the new one.
             // This helps use cache and reuse the model and just start/stop it when necessary.
-            if (mCurrentSoundModelHandle != INVALID_VALUE
+            if (mCurrentKeyphraseModelHandle != INVALID_VALUE
                     && !soundModel.equals(mCurrentSoundModel)) {
                 Slog.w(TAG, "Unloading previous sound model");
-                int status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
+                int status = mModule.unloadSoundModel(mCurrentKeyphraseModelHandle);
                 if (status != SoundTrigger.STATUS_OK) {
                     Slog.w(TAG, "unloadSoundModel call failed with " + status);
                 }
-                internalClearSoundModelLocked();
-                mStarted = false;
+                internalClearKeyphraseSoundModelLocked();
+                mKeyphraseStarted = false;
             }
 
             // If the previous recognition was by a different listener,
             // Notify them that it was stopped.
-            if (mActiveListener != null && mActiveListener.asBinder() != listener.asBinder()) {
+            if (mKeyphraseListener != null && mKeyphraseListener.asBinder() != listener.asBinder()) {
                 Slog.w(TAG, "Canceling previous recognition");
                 try {
-                    mActiveListener.onError(STATUS_ERROR);
+                    mKeyphraseListener.onError(STATUS_ERROR);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "RemoteException in onDetectionStopped", e);
                 }
-                mActiveListener = null;
+                mKeyphraseListener = null;
             }
 
             // Load the sound model if the current one is null.
-            int soundModelHandle = mCurrentSoundModelHandle;
-            if (mCurrentSoundModelHandle == INVALID_VALUE
+            int soundModelHandle = mCurrentKeyphraseModelHandle;
+            if (mCurrentKeyphraseModelHandle == INVALID_VALUE
                     || mCurrentSoundModel == null) {
                 int[] handle = new int[] { INVALID_VALUE };
                 int status = mModule.loadSoundModel(soundModel, handle);
@@ -213,18 +301,81 @@
             // Start the recognition.
             mRequested = true;
             mKeyphraseId = keyphraseId;
-            mCurrentSoundModelHandle = soundModelHandle;
+            mCurrentKeyphraseModelHandle = soundModelHandle;
             mCurrentSoundModel = soundModel;
             mRecognitionConfig = recognitionConfig;
             // Register the new listener. This replaces the old one.
             // There can only be a maximum of one active listener at any given time.
-            mActiveListener = listener;
+            mKeyphraseListener = listener;
 
             return updateRecognitionLocked(false /* don't notify for synchronous calls */);
         }
     }
 
     /**
+     * Stops recognition for the given generic sound model.
+     *
+     * @param modelId The identifier of the generic sound model for which
+     *        the recognition is to be stopped.
+     * @param listener The listener for the recognition events related to the given sound model.
+     *
+     * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
+     */
+    int stopGenericRecognition(UUID modelId, IRecognitionStatusCallback listener) {
+        if (listener == null) {
+            return STATUS_ERROR;
+        }
+
+        synchronized (mLock) {
+            ModelData modelData = mGenericModelDataMap.get(modelId);
+            if (modelData == null) {
+                Slog.w(TAG, "Attempting stopRecognition on invalid model with id:" + modelId);
+                return STATUS_ERROR;
+            }
+
+            IRecognitionStatusCallback currentCallback = modelData.getCallback();
+            if (DBG) {
+                Slog.d(TAG, "stopRecognition for modelId=" + modelId
+                        + ", listener=" + listener.asBinder());
+                Slog.d(TAG, "current callback ="
+                        + (currentCallback == null ? "null" : currentCallback.asBinder()));
+            }
+
+            if (mModuleProperties == null || mModule == null) {
+                Slog.w(TAG, "Attempting stopRecognition without the capability");
+                return STATUS_ERROR;
+            }
+
+            if (currentCallback == null || !modelData.modelStarted()) {
+                // startRecognition hasn't been called or it failed.
+                Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition");
+                return STATUS_ERROR;
+            }
+            if (currentCallback.asBinder() != listener.asBinder()) {
+                // We don't allow a different listener to stop the recognition than the one
+                // that started it.
+                Slog.w(TAG, "Attempting stopRecognition for another recognition");
+                return STATUS_ERROR;
+            }
+
+            int status = stopGenericRecognitionLocked(modelData, false /* don't notify for synchronous calls */);
+            if (status != SoundTrigger.STATUS_OK) {
+                return status;
+            }
+
+            // We leave the sound model loaded but not started, this helps us when we start
+            // back.
+            // Also clear the internal state once the recognition has been stopped.
+            modelData.clearState();
+            modelData.clearCallback();
+            if (!computeRecognitionRunning()) {
+                internalClearGlobalStateLocked();
+            }
+            return status;
+        }
+    }
+
+    /**
      * Stops recognition for the given {@link Keyphrase} if a recognition is
      * currently active.
      *
@@ -234,7 +385,7 @@
      *
      * @return One of {@link #STATUS_ERROR} or {@link #STATUS_OK}.
      */
-    int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
+    int stopKeyphraseRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
         if (listener == null) {
             return STATUS_ERROR;
         }
@@ -244,20 +395,20 @@
                 Slog.d(TAG, "stopRecognition for keyphraseId=" + keyphraseId
                         + ", listener=" + listener.asBinder());
                 Slog.d(TAG, "current listener="
-                        + (mActiveListener == null ? "null" : mActiveListener.asBinder()));
+                        + (mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder()));
             }
 
-            if (moduleProperties == null || mModule == null) {
+            if (mModuleProperties == null || mModule == null) {
                 Slog.w(TAG, "Attempting stopRecognition without the capability");
                 return STATUS_ERROR;
             }
 
-            if (mActiveListener == null) {
+            if (mKeyphraseListener == null) {
                 // startRecognition hasn't been called or it failed.
                 Slog.w(TAG, "Attempting stopRecognition without a successful startRecognition");
                 return STATUS_ERROR;
             }
-            if (mActiveListener.asBinder() != listener.asBinder()) {
+            if (mKeyphraseListener.asBinder() != listener.asBinder()) {
                 // We don't allow a different listener to stop the recognition than the one
                 // that started it.
                 Slog.w(TAG, "Attempting stopRecognition for another recognition");
@@ -274,7 +425,8 @@
             // We leave the sound model loaded but not started, this helps us when we start
             // back.
             // Also clear the internal state once the recognition has been stopped.
-            internalClearStateLocked();
+            internalClearKeyphraseStateLocked();
+            internalClearGlobalStateLocked();
             return status;
         }
     }
@@ -284,38 +436,56 @@
      */
     void stopAllRecognitions() {
         synchronized (mLock) {
-            if (moduleProperties == null || mModule == null) {
+            if (mModuleProperties == null || mModule == null) {
                 return;
             }
 
-            if (mCurrentSoundModelHandle == INVALID_VALUE) {
-                return;
+            // Stop Keyphrase recognition if one exists.
+            if (mCurrentKeyphraseModelHandle != INVALID_VALUE) {
+
+                mRequested = false;
+                int status = updateRecognitionLocked(
+                        false /* don't notify for synchronous calls */);
+                internalClearKeyphraseStateLocked();
             }
 
-            mRequested = false;
-            int status = updateRecognitionLocked(false /* don't notify for synchronous calls */);
-            internalClearStateLocked();
+            // Stop all generic recognition models.
+            for (ModelData model : mGenericModelDataMap.values()) {
+                if (model.modelStarted()) {
+                    int status = stopGenericRecognitionLocked(model,
+                            false /* do not notify for synchronous calls */);
+                    if (status != STATUS_OK) {
+                        // What else can we do if there is an error here.
+                        Slog.w(TAG, "Error stopping generic model: " + model.getHandle());
+                    }
+                    model.clearState();
+                    model.clearCallback();
+                }
+            }
+            internalClearGlobalStateLocked();
         }
     }
 
     public ModuleProperties getModuleProperties() {
-        return moduleProperties;
+        return mModuleProperties;
     }
 
     //---- SoundTrigger.StatusListener methods
     @Override
     public void onRecognition(RecognitionEvent event) {
-        if (event == null || !(event instanceof KeyphraseRecognitionEvent)) {
-            Slog.w(TAG, "Invalid recognition event!");
+        if (event == null) {
+            Slog.w(TAG, "Null recognition event!");
+            return;
+        }
+
+        if (!(event instanceof KeyphraseRecognitionEvent) &&
+                !(event instanceof GenericRecognitionEvent)) {
+            Slog.w(TAG, "Invalid recognition event type (not one of generic or keyphrase) !");
             return;
         }
 
         if (DBG) Slog.d(TAG, "onRecognition: " + event);
         synchronized (mLock) {
-            if (mActiveListener == null) {
-                Slog.w(TAG, "received onRecognition event without any listener for it");
-                return;
-            }
             switch (event.status) {
                 // Fire aborts/failures to all listeners since it's not tied to a keyphrase.
                 case SoundTrigger.RECOGNITION_STATUS_ABORT:
@@ -325,12 +495,60 @@
                     onRecognitionFailureLocked();
                     break;
                 case SoundTrigger.RECOGNITION_STATUS_SUCCESS:
-                    onRecognitionSuccessLocked((KeyphraseRecognitionEvent) event);
+
+                    if (isKeyphraseRecognitionEvent(event)) {
+                        onKeyphraseRecognitionSuccessLocked((KeyphraseRecognitionEvent) event);
+                    } else {
+                        onGenericRecognitionSuccessLocked((GenericRecognitionEvent) event);
+                    }
+
                     break;
             }
         }
     }
 
+    private boolean isKeyphraseRecognitionEvent(RecognitionEvent event) {
+        return mCurrentKeyphraseModelHandle == event.soundModelHandle;
+    }
+
+    private void onGenericRecognitionSuccessLocked(GenericRecognitionEvent event) {
+        if (event.status != SoundTrigger.RECOGNITION_STATUS_SUCCESS) {
+            return;
+        }
+        ModelData model = getModelDataFor(event.soundModelHandle);
+        if (model == null) {
+            Slog.w(TAG, "Generic recognition event: Model does not exist for handle: " +
+                    event.soundModelHandle);
+            return;
+        }
+
+        IRecognitionStatusCallback callback = model.getCallback();
+        if (callback == null) {
+            Slog.w(TAG, "Generic recognition event: Null callback for model handle: " +
+                    event.soundModelHandle);
+            return;
+        }
+
+        try {
+            callback.onDetected((GenericRecognitionEvent) event);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "RemoteException in onDetected", e);
+        }
+
+        model.setStopped();
+        RecognitionConfig config = model.getRecognitionConfig();
+        if (config == null) {
+            Slog.w(TAG, "Generic recognition event: Null RecognitionConfig for model handle: " +
+                    event.soundModelHandle);
+            return;
+        }
+
+        // TODO: Remove this block if the lower layer supports multiple triggers.
+        if (config.allowMultipleTriggers) {
+            startGenericRecognitionLocked(model, true /* notify */);
+        }
+    }
+
     @Override
     public void onSoundModelUpdate(SoundModelEvent event) {
         if (event == null) {
@@ -399,18 +617,25 @@
     private void onRecognitionFailureLocked() {
         Slog.w(TAG, "Recognition failure");
         try {
-            if (mActiveListener != null) {
-                mActiveListener.onError(STATUS_ERROR);
+            if (mKeyphraseListener != null) {
+                mKeyphraseListener.onError(STATUS_ERROR);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "RemoteException in onError", e);
         } finally {
-            internalClearStateLocked();
+            internalClearKeyphraseStateLocked();
+            internalClearGlobalStateLocked();
         }
     }
 
-    private void onRecognitionSuccessLocked(KeyphraseRecognitionEvent event) {
+    private void onKeyphraseRecognitionSuccessLocked(KeyphraseRecognitionEvent event) {
         Slog.i(TAG, "Recognition success");
+
+        if (mKeyphraseListener == null) {
+            Slog.w(TAG, "received onRecognition event without any listener for it");
+            return;
+        }
+
         KeyphraseRecognitionExtra[] keyphraseExtras =
                 ((KeyphraseRecognitionEvent) event).keyphraseExtras;
         if (keyphraseExtras == null || keyphraseExtras.length == 0) {
@@ -424,14 +649,14 @@
         }
 
         try {
-            if (mActiveListener != null) {
-                mActiveListener.onDetected((KeyphraseRecognitionEvent) event);
+            if (mKeyphraseListener != null) {
+                mKeyphraseListener.onDetected((KeyphraseRecognitionEvent) event);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "RemoteException in onDetected", e);
         }
 
-        mStarted = false;
+        mKeyphraseStarted = false;
         mRequested = mRecognitionConfig.allowMultipleTriggers;
         // TODO: Remove this block if the lower layer supports multiple triggers.
         if (mRequested) {
@@ -441,14 +666,16 @@
 
     private void onServiceDiedLocked() {
         try {
-            if (mActiveListener != null) {
-                mActiveListener.onError(SoundTrigger.STATUS_DEAD_OBJECT);
+            if (mKeyphraseListener != null) {
+                mKeyphraseListener.onError(SoundTrigger.STATUS_DEAD_OBJECT);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "RemoteException in onError", e);
         } finally {
-            internalClearSoundModelLocked();
-            internalClearStateLocked();
+            internalClearKeyphraseSoundModelLocked();
+            internalClearKeyphraseStateLocked();
+            internalClearGenericModelStateLocked();
+            internalClearGlobalStateLocked();
             if (mModule != null) {
                 mModule.detach();
                 mModule = null;
@@ -457,14 +684,14 @@
     }
 
     private int updateRecognitionLocked(boolean notify) {
-        if (mModule == null || moduleProperties == null
-                || mCurrentSoundModelHandle == INVALID_VALUE || mActiveListener == null) {
+        if (mModule == null || mModuleProperties == null
+                || mCurrentKeyphraseModelHandle == INVALID_VALUE || mKeyphraseListener == null) {
             // Nothing to do here.
             return STATUS_OK;
         }
 
         boolean start = mRequested && !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
-        if (start == mStarted) {
+        if (start == mKeyphraseStarted) {
             // No-op.
             return STATUS_OK;
         }
@@ -472,23 +699,24 @@
         // See if the recognition needs to be started.
         if (start) {
             // Start recognition.
-            int status = mModule.startRecognition(mCurrentSoundModelHandle, mRecognitionConfig);
+            int status = mModule.startRecognition(mCurrentKeyphraseModelHandle,
+                    mRecognitionConfig);
             if (status != SoundTrigger.STATUS_OK) {
                 Slog.w(TAG, "startRecognition failed with " + status);
                 // Notify of error if needed.
                 if (notify) {
                     try {
-                        mActiveListener.onError(status);
+                        mKeyphraseListener.onError(status);
                     } catch (RemoteException e) {
                         Slog.w(TAG, "RemoteException in onError", e);
                     }
                 }
             } else {
-                mStarted = true;
+                mKeyphraseStarted = true;
                 // Notify of resume if needed.
                 if (notify) {
                     try {
-                        mActiveListener.onRecognitionResumed();
+                        mKeyphraseListener.onRecognitionResumed();
                     } catch (RemoteException e) {
                         Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
                     }
@@ -499,7 +727,7 @@
             // Stop recognition (only if we haven't been aborted).
             int status = STATUS_OK;
             if (!mRecognitionAborted) {
-                status = mModule.stopRecognition(mCurrentSoundModelHandle);
+                status = mModule.stopRecognition(mCurrentKeyphraseModelHandle);
             } else {
                 mRecognitionAborted = false;
             }
@@ -507,17 +735,17 @@
                 Slog.w(TAG, "stopRecognition call failed with " + status);
                 if (notify) {
                     try {
-                        mActiveListener.onError(status);
+                        mKeyphraseListener.onError(status);
                     } catch (RemoteException e) {
                         Slog.w(TAG, "RemoteException in onError", e);
                     }
                 }
             } else {
-                mStarted = false;
+                mKeyphraseStarted = false;
                 // Notify of pause if needed.
                 if (notify) {
                     try {
-                        mActiveListener.onRecognitionPaused();
+                        mKeyphraseListener.onRecognitionPaused();
                     } catch (RemoteException e) {
                         Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
                     }
@@ -527,14 +755,11 @@
         }
     }
 
-    private void internalClearStateLocked() {
-        mStarted = false;
-        mRequested = false;
-
-        mKeyphraseId = INVALID_VALUE;
-        mRecognitionConfig = null;
-        mActiveListener = null;
-
+    // internalClearGlobalStateLocked() gets split into two routines. Cleanup that is
+    // specific to keyphrase sound models named as internalClearKeyphraseStateLocked() and
+    // internalClearGlobalStateLocked() for global state. The global cleanup routine will be used
+    // by the cleanup happening with the generic sound models.
+    private void internalClearGlobalStateLocked() {
         // Unregister from call state changes.
         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
 
@@ -545,8 +770,27 @@
         }
     }
 
-    private void internalClearSoundModelLocked() {
-        mCurrentSoundModelHandle = INVALID_VALUE;
+    private void internalClearKeyphraseStateLocked() {
+        mKeyphraseStarted = false;
+        mRequested = false;
+
+        mKeyphraseId = INVALID_VALUE;
+        mRecognitionConfig = null;
+        mKeyphraseListener = null;
+    }
+
+    private void internalClearGenericModelStateLocked() {
+        for (UUID modelId : mGenericModelDataMap.keySet()) {
+            ModelData modelData = mGenericModelDataMap.get(modelId);
+            modelData.clearState();
+            modelData.clearCallback();
+        }
+    }
+
+    // This routine is a replacement for internalClearSoundModelLocked(). However, we
+    // should see why this should be different from internalClearKeyphraseStateLocked().
+    private void internalClearKeyphraseSoundModelLocked() {
+        mCurrentKeyphraseModelHandle = INVALID_VALUE;
         mCurrentSoundModel = null;
     }
 
@@ -577,19 +821,251 @@
     void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mLock) {
             pw.print("  module properties=");
-            pw.println(moduleProperties == null ? "null" : moduleProperties);
+            pw.println(mModuleProperties == null ? "null" : mModuleProperties);
             pw.print("  keyphrase ID="); pw.println(mKeyphraseId);
-            pw.print("  sound model handle="); pw.println(mCurrentSoundModelHandle);
+            pw.print("  sound model handle="); pw.println(mCurrentKeyphraseModelHandle);
             pw.print("  sound model UUID=");
             pw.println(mCurrentSoundModel == null ? "null" : mCurrentSoundModel.uuid);
             pw.print("  current listener=");
-            pw.println(mActiveListener == null ? "null" : mActiveListener.asBinder());
+            pw.println(mKeyphraseListener == null ? "null" : mKeyphraseListener.asBinder());
 
             pw.print("  requested="); pw.println(mRequested);
-            pw.print("  started="); pw.println(mStarted);
+            pw.print("  started="); pw.println(mKeyphraseStarted);
             pw.print("  call active="); pw.println(mCallActive);
             pw.print("  power save mode active="); pw.println(mIsPowerSaveMode);
             pw.print("  service disabled="); pw.println(mServiceDisabled);
         }
     }
+
+    private void initializeTelephonyAndPowerStateListeners() {
+        // Get the current call state synchronously for the first recognition.
+        mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+
+        // Register for call state changes when the first call to start recognition occurs.
+        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+        // Register for power saver mode changes when the first call to start recognition
+        // occurs.
+        if (mPowerSaveModeListener == null) {
+            mPowerSaveModeListener = new PowerSaveModeListener();
+            mContext.registerReceiver(mPowerSaveModeListener,
+                    new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+        }
+        mIsPowerSaveMode = mPowerManager.isPowerSaveMode();
+    }
+
+    private ModelData getOrCreateGenericModelData(UUID modelId) {
+        ModelData modelData = mGenericModelDataMap.get(modelId);
+        if (modelData == null) {
+            modelData = new ModelData(modelId);
+            modelData.setTypeGeneric();
+            mGenericModelDataMap.put(modelId, modelData);
+        }
+        return modelData;
+    }
+
+    // Instead of maintaining a second hashmap of modelHandle -> ModelData, we just
+    // iterate through to find the right object (since we don't expect 100s of models
+    // to be stored).
+    private ModelData getModelDataFor(int modelHandle) {
+        // Fetch ModelData object corresponding to the model handle.
+        for (ModelData model : mGenericModelDataMap.values()) {
+            if (model.getHandle() == modelHandle) {
+                return model;
+            }
+        }
+        return null;
+    }
+
+    // Whether we are allowed to run any recognition at all. The conditions that let us run
+    // a recognition include: no active phone call or not being in a power save mode. Also,
+    // the native service should be enabled.
+    private boolean isRecognitionAllowed() {
+        return !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;
+    }
+
+    private int startGenericRecognitionLocked(ModelData modelData, boolean notify) {
+        IRecognitionStatusCallback callback = modelData.getCallback();
+        int handle = modelData.getHandle();
+        RecognitionConfig config = modelData.getRecognitionConfig();
+        if (callback == null || handle == INVALID_VALUE || config == null) {
+            // Nothing to do here.
+            Slog.w(TAG, "startGenericRecognition: Bad data passed in.");
+            return STATUS_ERROR;
+        }
+
+        if (!isRecognitionAllowed()) {
+            // Nothing to do here.
+            Slog.w(TAG, "startGenericRecognition requested but not allowed.");
+            return STATUS_OK;
+        }
+
+        int status = mModule.startRecognition(handle, config);
+        if (status != SoundTrigger.STATUS_OK) {
+            Slog.w(TAG, "startRecognition failed with " + status);
+            // Notify of error if needed.
+            if (notify) {
+                try {
+                    callback.onError(status);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onError", e);
+                }
+            }
+        } else {
+            modelData.setStarted();
+            // Notify of resume if needed.
+            if (notify) {
+                try {
+                    callback.onRecognitionResumed();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onRecognitionResumed", e);
+                }
+            }
+        }
+        return status;
+    }
+
+    private int stopGenericRecognitionLocked(ModelData modelData, boolean notify) {
+        IRecognitionStatusCallback callback = modelData.getCallback();
+
+        // Stop recognition (only if we haven't been aborted).
+        int status = mModule.stopRecognition(modelData.getHandle());
+        if (status != SoundTrigger.STATUS_OK) {
+            Slog.w(TAG, "stopRecognition call failed with " + status);
+            if (notify) {
+                try {
+                    callback.onError(status);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onError", e);
+                }
+            }
+        } else {
+            modelData.setStopped();
+            // Notify of pause if needed.
+            if (notify) {
+                try {
+                    callback.onRecognitionPaused();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
+                }
+            }
+        }
+        return status;
+    }
+
+    // Computes whether we have any recognition running at all (voice or generic). Sets
+    // the mRecognitionRunning variable with the result.
+    private boolean computeRecognitionRunning() {
+        synchronized (mLock) {
+            if (mModuleProperties == null || mModule == null) {
+                mRecognitionRunning = false;
+                return mRecognitionRunning;
+            }
+            if (mKeyphraseListener != null &&
+                    mKeyphraseStarted &&
+                    mCurrentKeyphraseModelHandle != INVALID_VALUE &&
+                    mCurrentSoundModel != null) {
+                mRecognitionRunning = true;
+                return mRecognitionRunning;
+            }
+            for (UUID modelId : mGenericModelDataMap.keySet()) {
+                ModelData modelData = mGenericModelDataMap.get(modelId);
+                if (modelData.modelStarted()) {
+                    mRecognitionRunning = true;
+                    return mRecognitionRunning;
+                }
+            }
+            mRecognitionRunning = false;
+        }
+        return mRecognitionRunning;
+    }
+
+    // This class encapsulates the callbacks, state, handles and any other information that
+    // represents a model.
+    private static class ModelData {
+        // Model not loaded (and hence not started).
+        static final int MODEL_NOTLOADED = 0;
+
+        // Loaded implies model was successfully loaded. Model not started yet.
+        static final int MODEL_LOADED = 1;
+
+        // Started implies model was successfully loaded and start was called.
+        static final int MODEL_STARTED = 2;
+
+        // One of MODEL_NOTLOADED, MODEL_LOADED, MODEL_STARTED (which implies loaded).
+        private int mModelState;
+
+        private UUID mModelId;
+
+        // One of SoundModel.TYPE_GENERIC or SoundModel.TYPE_KEYPHRASE. Initially set
+        // to SoundModel.TYPE_UNKNOWN;
+        private int mModelType = SoundModel.TYPE_UNKNOWN;
+        private IRecognitionStatusCallback mCallback = null;
+        private SoundModel mSoundModel = null;
+        private RecognitionConfig mRecognitionConfig = null;
+
+
+        // Model handle is an integer used by the HAL as an identifier for sound
+        // models.
+        private int mModelHandle = INVALID_VALUE;
+
+        ModelData(UUID modelId) {
+            mModelId = modelId;
+        }
+
+        synchronized void setTypeGeneric() {
+            mModelType = SoundModel.TYPE_GENERIC_SOUND;
+        }
+
+        synchronized void setCallback(IRecognitionStatusCallback callback) {
+            mCallback = callback;
+        }
+
+        synchronized IRecognitionStatusCallback getCallback() {
+            return mCallback;
+        }
+
+        synchronized boolean isModelLoaded() {
+            return (mModelState == MODEL_LOADED || mModelState == MODEL_STARTED) &&
+                    mSoundModel != null;
+        }
+
+        synchronized void setStarted() {
+            mModelState = MODEL_STARTED;
+        }
+
+        synchronized void setStopped() {
+            mModelState = MODEL_LOADED;
+        }
+
+        synchronized boolean modelStarted() {
+            return mModelState == MODEL_STARTED;
+        }
+
+        synchronized void clearState() {
+            mModelState = MODEL_NOTLOADED;
+            mSoundModel = null;
+            mModelHandle = INVALID_VALUE;
+        }
+
+        synchronized void clearCallback() {
+            mCallback = null;
+        }
+
+        synchronized void setHandle(int handle) {
+            mModelHandle = handle;
+        }
+
+        synchronized void setRecognitionConfig(RecognitionConfig config) {
+            mRecognitionConfig = config;
+        }
+
+        synchronized int getHandle() {
+            return mModelHandle;
+        }
+
+        synchronized RecognitionConfig getRecognitionConfig() {
+            return mRecognitionConfig;
+        }
+    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 682f4a4..251f314 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -15,6 +15,7 @@
  */
 
 package com.android.server.soundtrigger;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -47,13 +48,14 @@
  * @hide
  */
 public class SoundTriggerService extends SystemService {
-    static final String TAG = "SoundTriggerService";
-    static final boolean DEBUG = false;
+    private static final String TAG = "SoundTriggerService";
+    private static final boolean DEBUG = true;
 
     final Context mContext;
     private final SoundTriggerServiceStub mServiceStub;
     private final LocalSoundTriggerService mLocalSoundTriggerService;
     private SoundTriggerDbHelper mDbHelper;
+    private SoundTriggerHelper mSoundTriggerHelper;
 
     public SoundTriggerService(Context context) {
         super(context);
@@ -71,7 +73,8 @@
     @Override
     public void onBootPhase(int phase) {
         if (PHASE_SYSTEM_SERVICES_READY == phase) {
-            mLocalSoundTriggerService.initSoundTriggerHelper();
+            initSoundTriggerHelper();
+            mLocalSoundTriggerService.setSoundTriggerHelper(mSoundTriggerHelper);
         } else if (PHASE_THIRD_PARTY_APPS_CAN_START == phase) {
             mDbHelper = new SoundTriggerDbHelper(mContext);
         }
@@ -85,6 +88,20 @@
     public void onSwitchUser(int userHandle) {
     }
 
+    private synchronized void initSoundTriggerHelper() {
+        if (mSoundTriggerHelper == null) {
+            mSoundTriggerHelper = new SoundTriggerHelper(mContext);
+        }
+    }
+
+    private synchronized boolean isInitialized() {
+        if (mSoundTriggerHelper == null ) {
+            Slog.e(TAG, "SoundTriggerHelper not initialized.");
+            return false;
+        }
+        return true;
+    }
+
     class SoundTriggerServiceStub extends ISoundTriggerService.Stub {
         @Override
         public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
@@ -102,19 +119,32 @@
         }
 
         @Override
-        public void startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+        public int startRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback,
+                RecognitionConfig config) {
             enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
             if (DEBUG) {
                 Slog.i(TAG, "startRecognition(): Uuid : " + parcelUuid);
             }
+            if (!isInitialized()) return STATUS_ERROR;
+
+            GenericSoundModel model = getSoundModel(parcelUuid);
+            if (model == null) {
+                Slog.e(TAG, "Null model in database for id: " + parcelUuid);
+                return STATUS_ERROR;
+            }
+
+            return mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
+                    callback, config);
         }
 
         @Override
-        public void stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
+        public int stopRecognition(ParcelUuid parcelUuid, IRecognitionStatusCallback callback) {
             enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
             if (DEBUG) {
                 Slog.i(TAG, "stopRecognition(): Uuid : " + parcelUuid);
             }
+            if (!isInitialized()) return STATUS_ERROR;
+            return mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
         }
 
         @Override
@@ -123,10 +153,8 @@
             if (DEBUG) {
                 Slog.i(TAG, "getSoundModel(): id = " + soundModelId);
             }
-            SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(soundModelId.getUuid());
-            if (model == null) {
-                Slog.e(TAG, "Null model in database.");
-            }
+            SoundTrigger.GenericSoundModel model = mDbHelper.getGenericSoundModel(
+                    soundModelId.getUuid());
             return model;
         }
 
@@ -157,38 +185,49 @@
             mContext = context;
         }
 
-        void initSoundTriggerHelper() {
-            if (mSoundTriggerHelper == null) {
-                mSoundTriggerHelper = new SoundTriggerHelper(mContext);
-            }
+        synchronized void setSoundTriggerHelper(SoundTriggerHelper helper) {
+            mSoundTriggerHelper = helper;
         }
 
         @Override
         public int startRecognition(int keyphraseId, KeyphraseSoundModel soundModel,
                 IRecognitionStatusCallback listener, RecognitionConfig recognitionConfig) {
-            return mSoundTriggerHelper.startRecognition(keyphraseId, soundModel, listener,
+            if (!isInitialized()) return STATUS_ERROR;
+            return mSoundTriggerHelper.startKeyphraseRecognition(keyphraseId, soundModel, listener,
                     recognitionConfig);
         }
 
         @Override
-        public int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
-            return mSoundTriggerHelper.stopRecognition(keyphraseId, listener);
+        public synchronized int stopRecognition(int keyphraseId, IRecognitionStatusCallback listener) {
+            if (!isInitialized()) return STATUS_ERROR;
+            return mSoundTriggerHelper.stopKeyphraseRecognition(keyphraseId, listener);
         }
 
         @Override
         public void stopAllRecognitions() {
+            if (!isInitialized()) return;
             mSoundTriggerHelper.stopAllRecognitions();
         }
 
         @Override
         public ModuleProperties getModuleProperties() {
+            if (!isInitialized()) return null;
             return mSoundTriggerHelper.getModuleProperties();
         }
 
         @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (!isInitialized()) return;
             mSoundTriggerHelper.dump(fd, pw, args);
         }
+
+        private synchronized boolean isInitialized() {
+            if (mSoundTriggerHelper == null ) {
+                Slog.e(TAG, "SoundTriggerHelper not initialized.");
+                return false;
+            }
+            return true;
+        }
     }
 
     private void enforceCallingPermission(String permission) {
diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java
index 73cc4a5..3f32dbe 100644
--- a/telecomm/java/android/telecom/Log.java
+++ b/telecomm/java/android/telecom/Log.java
@@ -16,6 +16,8 @@
 
 package android.telecom;
 
+import android.os.AsyncTask;
+
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.IllegalFormatException;
@@ -38,8 +40,26 @@
     public static final boolean WARN = isLoggable(android.util.Log.WARN);
     public static final boolean ERROR = isLoggable(android.util.Log.ERROR);
 
+    private static MessageDigest sMessageDigest;
+
     private Log() {}
 
+    public static void initMd5Sum() {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            public Void doInBackground(Void... args) {
+                MessageDigest md;
+                try {
+                    md = MessageDigest.getInstance("SHA-1");
+                } catch (NoSuchAlgorithmException e) {
+                    md = null;
+                }
+                sMessageDigest = md;
+                return null;
+            }
+        }.execute();
+    }
+
     public static boolean isLoggable(int level) {
         return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level);
     }
@@ -137,15 +157,14 @@
     }
 
     private static String secureHash(byte[] input) {
-        MessageDigest messageDigest;
-        try {
-            messageDigest = MessageDigest.getInstance("SHA-1");
-        } catch (NoSuchAlgorithmException e) {
-            return null;
+        if (sMessageDigest != null) {
+            sMessageDigest.reset();
+            sMessageDigest.update(input);
+            byte[] result = sMessageDigest.digest();
+            return encodeHex(result);
+        } else {
+            return "Uninitialized SHA1";
         }
-        messageDigest.update(input);
-        byte[] result = messageDigest.digest();
-        return encodeHex(result);
     }
 
     private static String encodeHex(byte[] bytes) {
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index c122c5a..9f478df 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -498,6 +498,7 @@
             mContext = context;
         }
         mTelecomServiceOverride = telecomServiceImpl;
+        android.telecom.Log.initMd5Sum();
     }
 
     /**
@@ -774,9 +775,9 @@
     }
 
     /**
-     * Register a {@link PhoneAccount} for use by the system. When registering
-     * {@link PhoneAccount}s, existing registrations will be overwritten if the
-     * {@link PhoneAccountHandle} matches that of a {@link PhoneAccount} which is already
+     * Register a {@link PhoneAccount} for use by the system that will be stored in Device Encrypted
+     * storage. When registering {@link PhoneAccount}s, existing registrations will be overwritten
+     * if the {@link PhoneAccountHandle} matches that of a {@link PhoneAccount} which is already
      * registered. Once registered, the {@link PhoneAccount} is listed to the user as an option
      * when placing calls. The user may still need to enable the {@link PhoneAccount} within
      * the phone app settings before the account is usable.
@@ -1166,11 +1167,16 @@
     /**
      * Registers a new incoming call. A {@link ConnectionService} should invoke this method when it
      * has an incoming call. The specified {@link PhoneAccountHandle} must have been registered
-     * with {@link #registerPhoneAccount}. Once invoked, this method will cause the system to bind
-     * to the {@link ConnectionService} associated with the {@link PhoneAccountHandle} and request
-     * additional information about the call (See
-     * {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming call UI.
-     *
+     * with {@link #registerPhoneAccount} and the user must have enabled the corresponding
+     * {@link PhoneAccount}. This can be checked using {@link #getPhoneAccount}. Once invoked, this
+     * method will cause the system to bind to the {@link ConnectionService} associated with the
+     * {@link PhoneAccountHandle} and request additional information about the call
+     * (See {@link ConnectionService#onCreateIncomingConnection}) before starting the incoming
+     * call UI.
+     * <p>
+     * A {@link SecurityException} will be thrown if either the {@link PhoneAccountHandle} does not
+     * correspond to a registered {@link PhoneAccount} or the associated {@link PhoneAccount} is not
+     * currently enabled by the user.
      * @param phoneAccount A {@link PhoneAccountHandle} registered with
      *            {@link #registerPhoneAccount}.
      * @param extras A bundle that will be passed through to
diff --git a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
index 23a69d1..69259d0 100644
--- a/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
+++ b/telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl
@@ -17,6 +17,7 @@
 package com.android.ims.internal;
 
 import com.android.ims.ImsReasonInfo;
+
 /**
  * A listener type for receiving notifications about the changes to
  * the IMS connection(registration).
@@ -26,15 +27,36 @@
 interface IImsRegistrationListener {
     /**
      * Notifies the application when the device is connected to the IMS network.
+     *
+     * @deprecated see {@link registrationConnectedWithRadioTech}
      */
     void registrationConnected();
 
     /**
      * Notifies the application when the device is trying to connect the IMS network.
+     *
+     * @deprecated see {@link registrationProgressingWithRadioTech}
      */
     void registrationProgressing();
 
     /**
+     * Notifies the application when the device is connected to the IMS network.
+     *
+     * @param imsRadioTech the radio access technology. Valid values are {@code
+     * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}.
+     */
+    void registrationConnectedWithRadioTech(int imsRadioTech);
+
+    /**
+     * Notifies the application when the device is trying to connect the IMS network.
+     *
+     * @param imsRadioTech the radio access technology. Valid values are {@code
+     * RIL_RADIO_TECHNOLOGY_*} defined in {@link ServiceState}.
+     */
+    void registrationProgressingWithRadioTech(int imsRadioTech);
+
+
+    /**
      * Notifies the application when the device is disconnected from the IMS network.
      */
     void registrationDisconnected(in ImsReasonInfo imsReasonInfo);
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 429839f..bba357e 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -92,7 +92,33 @@
     int NO_SMS_TO_ACK = 48;                   /* ACK received when there is no SMS to ack */
     int NETWORK_ERR = 49;                     /* Received error from network */
     int REQUEST_RATE_LIMITED = 50;            /* Operation denied due to overly-frequent requests */
-
+    // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
+    // reveal particular replacement for Generic failure
+    int OEM_ERROR_1 = 501;
+    int OEM_ERROR_2 = 502;
+    int OEM_ERROR_3 = 503;
+    int OEM_ERROR_4 = 504;
+    int OEM_ERROR_5 = 505;
+    int OEM_ERROR_6 = 506;
+    int OEM_ERROR_7 = 507;
+    int OEM_ERROR_8 = 508;
+    int OEM_ERROR_9 = 509;
+    int OEM_ERROR_10 = 510;
+    int OEM_ERROR_11 = 511;
+    int OEM_ERROR_12 = 512;
+    int OEM_ERROR_13 = 513;
+    int OEM_ERROR_14 = 514;
+    int OEM_ERROR_15 = 515;
+    int OEM_ERROR_16 = 516;
+    int OEM_ERROR_17 = 517;
+    int OEM_ERROR_18 = 518;
+    int OEM_ERROR_19 = 519;
+    int OEM_ERROR_20 = 520;
+    int OEM_ERROR_21 = 521;
+    int OEM_ERROR_22 = 522;
+    int OEM_ERROR_23 = 523;
+    int OEM_ERROR_24 = 524;
+    int OEM_ERROR_25 = 525;
 
     /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
     int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
@@ -124,6 +150,26 @@
     int PREFERRED_NETWORK_MODE      = SystemProperties.getInt("ro.telephony.default_network",
             NETWORK_MODE_WCDMA_PREF);
 
+    int BAND_MODE_UNSPECIFIED = 0;      //"unspecified" (selected by baseband automatically)
+    int BAND_MODE_EURO = 1;             //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000)
+    int BAND_MODE_USA = 2;              //"US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900)
+    int BAND_MODE_JPN = 3;              //"JPN band" (WCDMA-800 / WCDMA-IMT-2000)
+    int BAND_MODE_AUS = 4;              //"AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000)
+    int BAND_MODE_AUS_2 = 5;            //"AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850)
+    int BAND_MODE_CELL_800 = 6;         //"Cellular" (800-MHz Band)
+    int BAND_MODE_PCS = 7;              //"PCS" (1900-MHz Band)
+    int BAND_MODE_JTACS = 8;            //"Band Class 3" (JTACS Band)
+    int BAND_MODE_KOREA_PCS = 9;        //"Band Class 4" (Korean PCS Band)
+    int BAND_MODE_5_450M = 10;          //"Band Class 5" (450-MHz Band)
+    int BAND_MODE_IMT2000 = 11;         //"Band Class 6" (2-GMHz IMT2000 Band)
+    int BAND_MODE_7_700M_2 = 12;        //"Band Class 7" (Upper 700-MHz Band)
+    int BAND_MODE_8_1800M = 13;         //"Band Class 8" (1800-MHz Band)
+    int BAND_MODE_9_900M = 14;          //"Band Class 9" (900-MHz Band)
+    int BAND_MODE_10_800M_2 = 15;       //"Band Class 10" (Secondary 800-MHz Band)
+    int BAND_MODE_EURO_PAMR_400M = 16;  //"Band Class 11" (400-MHz European PAMR Band)
+    int BAND_MODE_AWS = 17;             //"Band Class 15" (AWS Band)
+    int BAND_MODE_USA_2500M = 18;       //"Band Class 16" (US 2.5-GHz Band)
+
     int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
     int CDMA_CELL_BROADCAST_SMS_ENABLED  = 0;
 
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index ffb73f6..da43460 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -17,6 +17,7 @@
 package android.test.mock;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.PackageInstallObserver;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -806,6 +807,12 @@
         throw new UnsupportedOperationException();
     }
 
+    /** @hide */
+    @Override
+    public @Nullable String getServicesSystemSharedLibraryPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public FeatureInfo[] getSystemAvailableFeatures() {
         throw new UnsupportedOperationException();
@@ -817,6 +824,11 @@
     }
 
     @Override
+    public boolean hasSystemFeature(String name, int version) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public boolean isSafeMode() {
         throw new UnsupportedOperationException();
     }
@@ -847,8 +859,14 @@
 
     /** @hide */
     @Override
-    public boolean setPackageSuspendedAsUser(String packageName, boolean hidden, int userId) {
-        return false;
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean hidden, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        throw new UnsupportedOperationException();
     }
 
     /**
diff --git a/tests/BatteryWaster/res/layout/battery_waster.xml b/tests/BatteryWaster/res/layout/battery_waster.xml
index 57a5b55..ea76487 100644
--- a/tests/BatteryWaster/res/layout/battery_waster.xml
+++ b/tests/BatteryWaster/res/layout/battery_waster.xml
@@ -27,7 +27,6 @@
         android:layout_marginTop="25dp"
         android:saveEnabled="false"
         android:textSize="18sp"
-        android:textColor="#ffffffff"
         android:text="@string/waste_away"
         />
 
@@ -38,7 +37,6 @@
         android:layout_marginTop="25dp"
         android:saveEnabled="false"
         android:textSize="18sp"
-        android:textColor="#ffffffff"
         android:text="@string/wake_away"
         />
 
@@ -52,7 +50,6 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="25dp"
             android:textSize="12sp"
-            android:textColor="#ffffffff"
             />
     </ScrollView>
 
diff --git a/tests/SoundTriggerTestApp/Android.mk b/tests/SoundTriggerTestApp/Android.mk
index 7bcab5e..c327b09 100644
--- a/tests/SoundTriggerTestApp/Android.mk
+++ b/tests/SoundTriggerTestApp/Android.mk
@@ -8,5 +8,6 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_PRIVILEGED_MODULE := true
+LOCAL_CERTIFICATE := platform
 
 include $(BUILD_PACKAGE)
diff --git a/tests/SoundTriggerTestApp/AndroidManifest.xml b/tests/SoundTriggerTestApp/AndroidManifest.xml
index 40619da..a72b3dd 100644
--- a/tests/SoundTriggerTestApp/AndroidManifest.xml
+++ b/tests/SoundTriggerTestApp/AndroidManifest.xml
@@ -2,16 +2,22 @@
         package="com.android.test.soundtrigger">
 
     <uses-permission android:name="android.permission.MANAGE_SOUND_TRIGGER" />
-    <application
-         android:permission="android.permission.MANAGE_SOUND_TRIGGER">
+    <application>
         <activity
             android:name="TestSoundTriggerActivity"
             android:label="SoundTrigger Test Application"
-            android:theme="@android:style/Theme.Material.Light.Voice">
+            android:theme="@android:style/Theme.Material">
+            <!--
             <intent-filter>
                 <action android:name="com.android.intent.action.MANAGE_SOUND_TRIGGER" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
+            -->
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
         </activity>
     </application>
 </manifest>
diff --git a/tests/SoundTriggerTestApp/res/layout/main.xml b/tests/SoundTriggerTestApp/res/layout/main.xml
index 9d2b9d9..5ecc770 100644
--- a/tests/SoundTriggerTestApp/res/layout/main.xml
+++ b/tests/SoundTriggerTestApp/res/layout/main.xml
@@ -18,6 +18,11 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:orientation="vertical"
+    >
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
     >
 
     <Button
@@ -37,7 +42,57 @@
     <Button
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
+        android:text="@string/start_recog"
+        android:onClick="onStartRecognitionButtonClicked"
+        android:padding="20dp" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/stop_recog"
+        android:onClick="onStopRecognitionButtonClicked"
+        android:padding="20dp" />
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
         android:text="@string/unenroll"
         android:onClick="onUnEnrollButtonClicked"
         android:padding="20dp" />
-</LinearLayout>
\ No newline at end of file
+
+</LinearLayout>
+
+<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:padding="20dp"
+        android:orientation="vertical">
+   <RadioButton android:id="@+id/model_one"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/model_one"
+        android:onClick="onRadioButtonClicked"/>
+   <RadioButton android:id="@+id/model_two"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/model_two"
+        android:onClick="onRadioButtonClicked"/>
+   <RadioButton android:id="@+id/model_three"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/model_three"
+        android:onClick="onRadioButtonClicked"/>
+</RadioGroup>
+
+    <TextView
+        android:id="@+id/console"
+        android:gravity="left"
+        android:paddingTop="20pt"
+        android:layout_height="fill_parent"
+        android:layout_width="match_parent"
+        android:maxLines="40"
+        android:textSize="14dp"
+        android:scrollbars = "vertical"
+        android:text="@string/none">
+     </TextView>
+</LinearLayout>
diff --git a/tests/SoundTriggerTestApp/res/values/strings.xml b/tests/SoundTriggerTestApp/res/values/strings.xml
index 07bac2a..5f0fb1d 100644
--- a/tests/SoundTriggerTestApp/res/values/strings.xml
+++ b/tests/SoundTriggerTestApp/res/values/strings.xml
@@ -16,7 +16,13 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="enroll">Enroll</string>
-    <string name="reenroll">Re-enroll</string>
-    <string name="unenroll">Un-enroll</string>
-</resources>
\ No newline at end of file
+    <string name="enroll">Load</string>
+    <string name="reenroll">Re-load</string>
+    <string name="unenroll">Un-load</string>
+    <string name="start_recog">Start</string>
+    <string name="stop_recog">Stop</string>
+    <string name="model_one">Model One</string>
+    <string name="model_two">Model Two</string>
+    <string name="model_three">Model Three</string>
+    <string name="none">Debug messages appear here:</string>
+</resources>
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
index 4702835..1c95c25 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/SoundTriggerUtil.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.hardware.soundtrigger.SoundTrigger;
 import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.soundtrigger.SoundTriggerDetector;
 import android.media.soundtrigger.SoundTriggerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -28,6 +29,7 @@
 
 import com.android.internal.app.ISoundTriggerService;
 
+import java.lang.RuntimeException;
 import java.util.UUID;
 
 /**
@@ -56,6 +58,9 @@
      */
     public boolean addOrUpdateSoundModel(GenericSoundModel soundModel) {
         try {
+            if (soundModel == null) {
+                throw new RuntimeException("Bad sound model");
+            }
             mSoundTriggerService.updateSoundModel(soundModel);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in updateSoundModel", e);
@@ -112,4 +117,10 @@
     public void deleteSoundModelUsingManager(UUID modelId) {
             mSoundTriggerManager.deleteModel(modelId);
     }
+
+    public SoundTriggerDetector createSoundTriggerDetector(UUID modelId,
+            SoundTriggerDetector.Callback callback) {
+        return mSoundTriggerManager.createSoundTriggerDetector(modelId, callback, null);
+    }
+
 }
diff --git a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
index 966179b..96a6966 100644
--- a/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
+++ b/tests/SoundTriggerTestApp/src/com/android/test/soundtrigger/TestSoundTriggerActivity.java
@@ -22,11 +22,17 @@
 import android.app.Activity;
 import android.hardware.soundtrigger.SoundTrigger;
 import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.media.AudioFormat;
+import android.media.soundtrigger.SoundTriggerDetector;
 import android.media.soundtrigger.SoundTriggerManager;
+import android.text.Editable;
+import android.text.method.ScrollingMovementMethod;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.util.Log;
 import android.view.View;
+import android.widget.RadioButton;
+import android.widget.TextView;
 import android.widget.Toast;
 
 public class TestSoundTriggerActivity extends Activity {
@@ -35,42 +41,75 @@
 
     private SoundTriggerUtil mSoundTriggerUtil;
     private Random mRandom;
-    private UUID mModelUuid = UUID.randomUUID();
+    private UUID mModelUuid1 = UUID.randomUUID();
     private UUID mModelUuid2 = UUID.randomUUID();
+    private UUID mModelUuid3 = UUID.randomUUID();
     private UUID mVendorUuid = UUID.randomUUID();
 
+    private SoundTriggerDetector mDetector1 = null;
+    private SoundTriggerDetector mDetector2 = null;
+    private SoundTriggerDetector mDetector3 = null;
+
+    private TextView mDebugView = null;
+    private int mSelectedModelId = 1;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         if (DBG) Log.d(TAG, "onCreate");
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
+        mDebugView = (TextView) findViewById(R.id.console);
+        mDebugView.setText(mDebugView.getText(), TextView.BufferType.EDITABLE);
+        mDebugView.setMovementMethod(new ScrollingMovementMethod());
         mSoundTriggerUtil = new SoundTriggerUtil(this);
         mRandom = new Random();
     }
 
+    private void postMessage(String msg) {
+        Log.i(TAG, "Posted: " + msg);
+        ((Editable) mDebugView.getText()).append(msg + "\n");
+    }
+
+    private UUID getSelectedUuid() {
+        if (mSelectedModelId == 2) return mModelUuid2;
+        if (mSelectedModelId == 3) return mModelUuid3;
+        return mModelUuid1;  // Default.
+    }
+
+    private void setDetector(SoundTriggerDetector detector) {
+        if (mSelectedModelId == 2) mDetector2 = detector;
+        if (mSelectedModelId == 3) mDetector3 = detector;
+        mDetector1 = detector;
+    }
+
+    private SoundTriggerDetector getDetector() {
+        if (mSelectedModelId == 2) return mDetector2;
+        if (mSelectedModelId == 3) return mDetector3;
+        return mDetector1;
+    }
+
     /**
      * Called when the user clicks the enroll button.
      * Performs a fresh enrollment.
      */
     public void onEnrollButtonClicked(View v) {
+        postMessage("Loading model: " + mSelectedModelId);
         // Generate a fake model to push.
         byte[] data = new byte[1024];
         mRandom.nextBytes(data);
-        GenericSoundModel model = new GenericSoundModel(mModelUuid, mVendorUuid, data);
+        UUID modelUuid = getSelectedUuid();
+        GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data);
 
         boolean status = mSoundTriggerUtil.addOrUpdateSoundModel(model);
         if (status) {
             Toast.makeText(
-                    this, "Successfully created sound trigger model UUID=" + mModelUuid, Toast.LENGTH_SHORT)
-                    .show();
+                    this, "Successfully created sound trigger model UUID=" + modelUuid,
+                    Toast.LENGTH_SHORT).show();
         } else {
-            Toast.makeText(this, "Failed to enroll!!!" + mModelUuid, Toast.LENGTH_SHORT).show();
+            Toast.makeText(this, "Failed to enroll!!!" + modelUuid, Toast.LENGTH_SHORT).show();
         }
 
         // Test the SoundManager API.
-        SoundTriggerManager.Model tmpModel = SoundTriggerManager.Model.create(mModelUuid2,
-                mVendorUuid, data);
-        mSoundTriggerUtil.addOrUpdateSoundModel(tmpModel);
     }
 
     /**
@@ -78,12 +117,14 @@
      * Clears the enrollment information for the user.
      */
     public void onUnEnrollButtonClicked(View v) {
-        GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid);
+        postMessage("Unloading model: " + mSelectedModelId);
+        UUID modelUuid = getSelectedUuid();
+        GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(modelUuid);
         if (soundModel == null) {
             Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
             return;
         }
-        boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid);
+        boolean status = mSoundTriggerUtil.deleteSoundModel(mModelUuid1);
         if (status) {
             Toast.makeText(this, "Successfully deleted model UUID=" + soundModel.uuid,
                     Toast.LENGTH_SHORT)
@@ -91,7 +132,6 @@
         } else {
             Toast.makeText(this, "Failed to delete sound model!!!", Toast.LENGTH_SHORT).show();
         }
-        mSoundTriggerUtil.deleteSoundModelUsingManager(mModelUuid2);
     }
 
     /**
@@ -99,7 +139,9 @@
      * Uses the previously enrolled sound model and makes changes to it before pushing it back.
      */
     public void onReEnrollButtonClicked(View v) {
-        GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(mModelUuid);
+        postMessage("Re-loading model: " + mSelectedModelId);
+        UUID modelUuid = getSelectedUuid();
+        GenericSoundModel soundModel = mSoundTriggerUtil.getSoundModel(modelUuid);
         if (soundModel == null) {
             Toast.makeText(this, "Sound model not found!!!", Toast.LENGTH_SHORT).show();
             return;
@@ -118,4 +160,86 @@
             Toast.makeText(this, "Failed to re-enroll!!!", Toast.LENGTH_SHORT).show();
         }
     }
+
+    public void onStartRecognitionButtonClicked(View v) {
+        UUID modelUuid = getSelectedUuid();
+        SoundTriggerDetector detector = getDetector();
+        if (detector == null) {
+            Log.i(TAG, "Created an instance of the SoundTriggerDetector.");
+            detector = mSoundTriggerUtil.createSoundTriggerDetector(modelUuid,
+                    new DetectorCallback());
+            setDetector(detector);
+        }
+        postMessage("Triggering start recognition for model: " + mSelectedModelId);
+        if (!detector.startRecognition(
+                SoundTriggerDetector.RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS)) {
+            Log.e(TAG, "Fast failure attempting to start recognition.");
+        }
+    }
+
+    public void onStopRecognitionButtonClicked(View v) {
+        SoundTriggerDetector detector = getDetector();
+        if (detector == null) {
+            Log.e(TAG, "Stop called on null detector.");
+            return;
+        }
+        postMessage("Triggering stop recognition for model: " + mSelectedModelId);
+        if (!detector.stopRecognition()) {
+            Log.e(TAG, "Fast failure attempting to stop recognition.");
+        }
+    }
+
+    public void onRadioButtonClicked(View view) {
+        // Is the button now checked?
+        boolean checked = ((RadioButton) view).isChecked();
+        // Check which radio button was clicked
+        switch(view.getId()) {
+            case R.id.model_one:
+                if (checked) mSelectedModelId = 1;
+                postMessage("Selected model one.");
+                break;
+            case R.id.model_two:
+                if (checked) mSelectedModelId = 2;
+                postMessage("Selected model two.");
+                break;
+            case R.id.model_three:
+                if (checked) mSelectedModelId = 3;
+                postMessage("Selected model three.");
+                break;
+        }
+    }
+
+    // Implementation of SoundTriggerDetector.Callback.
+    public class DetectorCallback extends SoundTriggerDetector.Callback {
+        public void onAvailabilityChanged(int status) {
+            postMessage("Availability changed to: " + status);
+        }
+
+        public void onDetected(SoundTriggerDetector.EventPayload event) {
+            postMessage("onDetected(): " + eventPayloadToString(event));
+        }
+
+        public void onError() {
+            postMessage("onError()");
+        }
+
+        public void onRecognitionPaused() {
+            postMessage("onRecognitionPaused()");
+        }
+
+        public void onRecognitionResumed() {
+            postMessage("onRecognitionResumed()");
+        }
+    }
+
+    private String eventPayloadToString(SoundTriggerDetector.EventPayload event) {
+        String result = "EventPayload(";
+        AudioFormat format =  event.getCaptureAudioFormat();
+        result = result + "AudioFormat: " + ((format == null) ? "null" : format.toString());
+        byte[] triggerAudio = event.getTriggerAudio();
+        result = result + "TriggerAudio: " + (triggerAudio == null ? "null" : triggerAudio.length);
+        result = result + "CaptureSession: " + event.getCaptureSession();
+        result += " )";
+        return result;
+    }
 }
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 3a30230..46de201 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -37,6 +37,7 @@
 
 // private NM API
 import android.app.INotificationManager;
+import android.widget.Toast;
 
 public class NotificationTestList extends TestActivity
 {
@@ -233,6 +234,30 @@
                 }
             },
 
+            new Test("Is blocked?") {
+                public void run() {
+                    Toast.makeText(NotificationTestList.this,
+                            "package enabled? " + mNM.areNotificationsEnabled(),
+                            Toast.LENGTH_LONG).show();
+                }
+            },
+
+            new Test("Topic banana importance?") {
+                public void run() {
+                    Toast.makeText(NotificationTestList.this,
+                            "bananas importance? " + mNM.getImportance("bananas"),
+                            Toast.LENGTH_LONG).show();
+                }
+            },
+
+            new Test("Topic garbage importance?") {
+                public void run() {
+                    Toast.makeText(NotificationTestList.this,
+                            "garbage importance? " + mNM.getImportance("garbage"),
+                            Toast.LENGTH_LONG).show();
+                }
+            },
+
         new Test("Whens") {
             public void run()
             {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 4d9ba6c..18a1943 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1883,8 +1883,6 @@
                     //printf("Comment of %s: %s\n", String8(e).string(),
                     //        String8(cmt).string());
                     syms->appendComment(String8(e), String16(cmt), srcPos);
-                } else {
-                    //printf("No comment for %s\n", String8(e).string());
                 }
                 syms->makeSymbolPublic(String8(e), srcPos);
             } else if (strcmp16(block.getElementName(&len), uses_permission16.string()) == 0) {
@@ -2535,10 +2533,6 @@
             fprintf(fp,
                     "%s/** %s\n",
                     getIndentSpace(indent), cmt.string());
-        } else if (sym.isPublic && !includePrivate) {
-            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
-                assets->getPackage().string(), className.string(),
-                String8(sym.name).string());
         }
         String16 typeComment(sym.typeComment);
         if (typeComment.size() > 0) {
@@ -2581,10 +2575,6 @@
                      "%s */\n",
                     getIndentSpace(indent), cmt.string(),
                     getIndentSpace(indent));
-        } else if (sym.isPublic && !includePrivate) {
-            sym.sourcePos.warning("No comment for public symbol %s:%s/%s",
-                assets->getPackage().string(), className.string(),
-                String8(sym.name).string());
         }
         ann.printAnnotations(fp, getIndentSpace(indent));
         fprintf(fp, "%spublic static final String %s=\"%s\";\n",
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index f74b93a..cb82ac3 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -38,11 +38,15 @@
 	io/ZipArchive.cpp \
 	link/AutoVersioner.cpp \
 	link/ManifestFixer.cpp \
+	link/ProductFilter.cpp \
 	link/PrivateAttributeMover.cpp \
 	link/ReferenceLinker.cpp \
 	link/TableMerger.cpp \
 	link/XmlReferenceLinker.cpp \
 	process/SymbolTable.cpp \
+	proto/ProtoHelpers.cpp \
+	proto/TableProtoDeserializer.cpp \
+	proto/TableProtoSerializer.cpp \
 	unflatten/BinaryResourceParser.cpp \
 	unflatten/ResChunkPullParser.cpp \
 	util/BigBuffer.cpp \
@@ -67,23 +71,25 @@
 	xml/XmlPullParser.cpp \
 	xml/XmlUtil.cpp
 
+sources += Format.proto
+
 testSources := \
 	compile/IdAssigner_test.cpp \
 	compile/PseudolocaleGenerator_test.cpp \
 	compile/Pseudolocalizer_test.cpp \
 	compile/XmlIdCollector_test.cpp \
 	filter/ConfigFilter_test.cpp \
-	flatten/FileExportWriter_test.cpp \
 	flatten/TableFlattener_test.cpp \
 	flatten/XmlFlattener_test.cpp \
 	link/AutoVersioner_test.cpp \
 	link/ManifestFixer_test.cpp \
 	link/PrivateAttributeMover_test.cpp \
+	link/ProductFilter_test.cpp \
 	link/ReferenceLinker_test.cpp \
 	link/TableMerger_test.cpp \
 	link/XmlReferenceLinker_test.cpp \
 	process/SymbolTable_test.cpp \
-	unflatten/FileExportHeaderReader_test.cpp \
+	proto/TableProtoSerializer_test.cpp \
 	util/BigBuffer_test.cpp \
 	util/Maybe_test.cpp \
 	util/StringPiece_test.cpp \
@@ -105,6 +111,7 @@
 
 toolSources := \
 	compile/Compile.cpp \
+	dump/Dump.cpp \
 	link/Link.cpp
 
 hostLdLibs :=
@@ -119,6 +126,9 @@
 	libpng \
 	libbase
 
+hostSharedLibs := \
+	libprotobuf-cpp-lite
+
 ifneq ($(strip $(USE_MINGW)),)
 	hostStaticLibs += libz
 else
@@ -127,21 +137,23 @@
 
 cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG
 cppFlags := -std=c++11 -Wno-missing-field-initializers -fno-exceptions -fno-rtti
+protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST)
 
 # ==========================================================
 # Build the host static library: libaapt2
 # ==========================================================
 include $(CLEAR_VARS)
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 LOCAL_MODULE := libaapt2
 
 LOCAL_SRC_FILES := $(sources)
 LOCAL_STATIC_LIBRARIES += $(hostStaticLibs)
 LOCAL_CFLAGS += $(cFlags)
 LOCAL_CPPFLAGS += $(cppFlags)
+LOCAL_C_INCLUDES += $(protoIncludes)
 
 include $(BUILD_HOST_STATIC_LIBRARY)
 
-
 # ==========================================================
 # Build the host tests: libaapt2_tests
 # ==========================================================
@@ -152,9 +164,11 @@
 LOCAL_SRC_FILES := $(testSources)
 
 LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
+LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
 LOCAL_LDLIBS += $(hostLdLibs)
 LOCAL_CFLAGS += $(cFlags)
 LOCAL_CPPFLAGS += $(cppFlags)
+LOCAL_C_INCLUDES += $(protoIncludes)
 
 include $(BUILD_HOST_NATIVE_TEST)
 
@@ -167,9 +181,11 @@
 LOCAL_SRC_FILES := $(main) $(toolSources)
 
 LOCAL_STATIC_LIBRARIES += libaapt2 $(hostStaticLibs)
+LOCAL_SHARED_LIBRARIES += $(hostSharedLibs)
 LOCAL_LDLIBS += $(hostLdLibs)
 LOCAL_CFLAGS += $(cFlags)
 LOCAL_CPPFLAGS += $(cppFlags)
+LOCAL_C_INCLUDES += $(protoIncludes)
 
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index b4e75f9..4bea129 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -144,8 +144,8 @@
 
                 PrintVisitor visitor;
                 for (const auto& value : entry->values) {
-                    std::cout << "      (" << value.config << ") ";
-                    value.value->accept(&visitor);
+                    std::cout << "      (" << value->config << ") ";
+                    value->value->accept(&visitor);
                     std::cout << std::endl;
                 }
             }
@@ -176,7 +176,7 @@
         if (result) {
             ResourceEntry* entry = result.value().entry;
             for (const auto& value : entry->values) {
-                if (Style* style = valueCast<Style>(value.value.get())) {
+                if (Style* style = valueCast<Style>(value->value.get())) {
                     if (style->parent && style->parent.value().name) {
                         parents.insert(style->parent.value().name.value());
                         stylesToVisit.push(style->parent.value().name.value());
diff --git a/tools/aapt2/Format.proto b/tools/aapt2/Format.proto
new file mode 100644
index 0000000..d05425c
--- /dev/null
+++ b/tools/aapt2/Format.proto
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package aapt.pb;
+
+message ConfigDescription {
+	optional bytes data = 1;
+	optional string product = 2;
+}
+
+message StringPool {
+	optional bytes data = 1;
+}
+
+message CompiledFile {
+	message Symbol {
+		optional string resource_name = 1;
+		optional uint32 line_no = 2;
+	}
+	
+	optional string resource_name = 1;
+	optional ConfigDescription config = 2;
+	optional string source_path = 3;
+	repeated Symbol exported_symbols = 4;
+}
+
+message ResourceTable {
+	optional StringPool string_pool = 1;
+	optional StringPool source_pool = 2;
+	optional StringPool symbol_pool = 3;
+	repeated Package packages = 4;
+}
+
+message Package {
+	optional uint32 package_id = 1;
+	optional string package_name = 2;
+	repeated Type types = 3;
+}
+
+message Type {	
+	optional uint32 id = 1;
+	optional string name = 2;
+	repeated Entry entries = 3;
+}
+
+message SymbolStatus {
+	enum Visibility {
+		Unknown = 0;
+		Private = 1;
+		Public = 2;
+	}
+	optional Visibility visibility = 1;
+	optional Source source = 2;
+	optional string comment = 3;
+}
+
+message Entry {
+	optional uint32 id = 1;
+	optional string name = 2;
+	optional SymbolStatus symbol_status = 3;
+	repeated ConfigValue config_values = 4;
+}
+
+message ConfigValue {
+	optional ConfigDescription config = 1;
+	optional Value value = 2;
+}
+
+message Source {
+	optional uint32 path_idx = 1;
+	optional uint32 line_no = 2;
+	optional uint32 col_no = 3;
+}
+
+message Reference {
+	enum Type {
+		Ref = 0;
+		Attr = 1;
+	}
+	optional Type type = 1;
+	optional uint32 id = 2;
+	optional uint32 symbol_idx = 3;
+	optional bool private = 4;
+}
+
+message Id {
+}
+
+message String {
+	optional uint32 idx = 1;
+}
+
+message RawString {
+	optional uint32 idx = 1;
+}
+
+message FileReference {
+	optional uint32 path_idx = 1;
+}
+
+message Primitive {
+	optional uint32 type = 1;
+	optional uint32 data = 2;
+}
+
+message Attribute {
+	message Symbol {
+		optional Source source = 1;
+		optional string comment = 2;
+		optional Reference name = 3;
+		optional uint32 value = 4;
+	}
+	optional uint32 format_flags = 1;
+	optional int32 min_int = 2;
+	optional int32 max_int = 3;
+	repeated Symbol symbols = 4;
+}
+
+message Style {
+	message Entry {
+		optional Source source = 1;
+		optional string comment = 2;
+		optional Reference key = 3;
+		optional Item item = 4;
+	}
+
+	optional Reference parent = 1;
+	optional Source parent_source = 2;
+	repeated Entry entries = 3;
+}
+
+message Styleable {
+	message Entry {
+		optional Source source = 1;
+		optional string comment = 2;
+		optional Reference attr = 3;
+	}
+	repeated Entry entries = 1;
+}
+
+message Array {
+	message Entry {
+		optional Source source = 1;
+		optional string comment = 2;
+		optional Item item = 3;
+	}
+	repeated Entry entries = 1;
+}
+
+message Plural {
+	enum Arity {
+		Zero = 0;
+		One = 1;
+		Two = 2;
+		Few = 3;
+		Many = 4;
+		Other = 5;
+	}
+		
+	message Entry {
+		optional Source source = 1;
+		optional string comment = 2;
+		optional Arity arity = 3;
+		optional Item item = 4;
+	}
+	repeated Entry entries = 1;
+}
+
+message Item {
+	optional Reference ref = 1;
+	optional String str = 2;
+	optional RawString raw_str = 3;
+	optional FileReference file = 4;
+	optional Id id = 5;
+	optional Primitive prim = 6;
+}
+
+message CompoundValue {
+	optional Attribute attr = 1;
+	optional Style style = 2;
+	optional Styleable styleable = 3;
+	optional Array array = 4;
+	optional Plural plural = 5;
+}
+
+message Value {
+	optional Source source = 1;
+	optional string comment = 2;
+	optional bool weak = 3;
+	
+	optional Item item = 4;
+	optional CompoundValue compound_value = 5;	
+}
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 248e7ad..a2fadd9 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -23,6 +23,7 @@
 
 extern int compile(const std::vector<StringPiece>& args);
 extern int link(const std::vector<StringPiece>& args);
+extern int dump(const std::vector<StringPiece>& args);
 
 } // namespace aapt
 
@@ -41,12 +42,14 @@
             return aapt::compile(args);
         } else if (command == "link" || command == "l") {
             return aapt::link(args);
+        } else if (command == "dump" || command == "d") {
+            return aapt::dump(args);
         }
         std::cerr << "unknown command '" << command << "'\n";
     } else {
         std::cerr << "no command specified\n";
     }
 
-    std::cerr << "\nusage: aapt2 [compile|link] ..." << std::endl;
+    std::cerr << "\nusage: aapt2 [compile|link|dump] ..." << std::endl;
     return 1;
 }
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index b37d366..b100e84 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -19,7 +19,6 @@
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
-#include "util/Comparators.h"
 #include "util/ImmutableMap.h"
 #include "util/Util.h"
 #include "xml/XmlPullParser.h"
@@ -71,6 +70,7 @@
 struct ParsedResource {
     ResourceName name;
     ConfigDescription config;
+    std::string product;
     Source source;
     ResourceId id;
     Maybe<SymbolState> symbolState;
@@ -79,35 +79,6 @@
     std::list<ParsedResource> childResources;
 };
 
-bool ResourceParser::shouldStripResource(const ResourceNameRef& name,
-                                         const Maybe<std::u16string>& product) const {
-    if (product) {
-        for (const std::u16string& productToMatch : mOptions.products) {
-            if (product.value() == productToMatch) {
-                // We specified a product, and it is in the list, so don't strip.
-                return false;
-            }
-        }
-    }
-
-    // Nothing matched, try 'default'. Default only matches if we didn't already use another
-    // product variant.
-    if (!product || product.value() == u"default") {
-        if (Maybe<ResourceTable::SearchResult> result = mTable->findResource(name)) {
-            const ResourceEntry* entry = result.value().entry;
-            auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), mConfig,
-                                         cmp::lessThanConfig);
-            if (iter != entry->values.end() && iter->config == mConfig && !iter->value->isWeak()) {
-                // We have a value for this config already, and it is not weak,
-                // so filter out this default.
-                return true;
-            }
-        }
-        return false;
-    }
-    return true;
-}
-
 // Recursively adds resources to the ResourceTable.
 static bool addResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) {
     if (res->symbolState) {
@@ -125,7 +96,8 @@
         res->value->setComment(std::move(res->comment));
         res->value->setSource(std::move(res->source));
 
-        if (!table->addResource(res->name, res->id, res->config, std::move(res->value), diag)) {
+        if (!table->addResource(res->name, res->id, res->config, res->product,
+                                std::move(res->value), diag)) {
             return false;
         }
     }
@@ -295,9 +267,8 @@
         parsedResource.comment = std::move(comment);
 
         // Extract the product name if it exists.
-        Maybe<std::u16string> product;
         if (Maybe<StringPiece16> maybeProduct = xml::findNonEmptyAttribute(parser, u"product")) {
-            product = maybeProduct.value().toString();
+            parsedResource.product = util::utf16ToUtf8(maybeProduct.value());
         }
 
         // Parse the resource regardless of product.
@@ -306,12 +277,7 @@
             continue;
         }
 
-        // We successfully parsed the resource. Check if we should include it or strip it.
-        if (shouldStripResource(parsedResource.name, product)) {
-            // Record that we stripped out this resource name.
-            // We will check that at least one variant of this resource was included.
-            strippedResources.insert(parsedResource.name);
-        } else if (!addResourcesToTable(mTable, mDiag, &parsedResource)) {
+        if (!addResourcesToTable(mTable, mDiag, &parsedResource)) {
             error = true;
         }
     }
@@ -524,7 +490,7 @@
         // name.package can be empty here, as it will assume the package name of the table.
         std::unique_ptr<Id> id = util::make_unique<Id>();
         id->setSource(mSource.withLine(beginXmlLine));
-        mTable->addResource(name, {}, std::move(id), mDiag);
+        mTable->addResource(name, {}, {}, std::move(id), mDiag);
     };
 
     // Process the raw value.
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 51cbbe1..ee5b337 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -34,13 +34,6 @@
 
 struct ResourceParserOptions {
     /**
-     * Optional product names by which to filter resources.
-     * This is like a preprocessor definition in that we strip out resources
-     * that don't match before we compile them.
-     */
-    std::vector<std::u16string> products;
-
-    /**
      * Whether the default setting for this parser is to allow translation.
      */
     bool translatable = true;
@@ -106,9 +99,6 @@
     bool parseArrayImpl(xml::XmlPullParser* parser, ParsedResource* outResource, uint32_t typeMask);
     bool parsePlural(xml::XmlPullParser* parser, ParsedResource* outResource);
 
-    bool shouldStripResource(const ResourceNameRef& name,
-                             const Maybe<std::u16string>& product) const;
-
     IDiagnostics* mDiag;
     ResourceTable* mTable;
     Source mSource;
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index cf0fcd1..3450de9 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -48,24 +48,13 @@
     }
 
     ::testing::AssertionResult testParse(const StringPiece& str) {
-        return testParse(str, ConfigDescription{}, {});
+        return testParse(str, ConfigDescription{});
     }
 
     ::testing::AssertionResult testParse(const StringPiece& str, const ConfigDescription& config) {
-        return testParse(str, config, {});
-    }
-
-    ::testing::AssertionResult testParse(const StringPiece& str,
-                                         std::initializer_list<std::u16string> products) {
-        return testParse(str, {}, std::move(products));
-    }
-
-    ::testing::AssertionResult testParse(const StringPiece& str, const ConfigDescription& config,
-                                         std::initializer_list<std::u16string> products) {
         std::stringstream input(kXmlPreamble);
         input << "<resources>\n" << str << "\n</resources>" << std::endl;
         ResourceParserOptions parserOptions;
-        parserOptions.products = products;
         ResourceParser parser(mContext->getDiagnostics(), &mTable, Source{ "test" }, config,
                               parserOptions);
         xml::XmlPullParser xmlParser(input);
@@ -546,7 +535,7 @@
     ASSERT_NE(nullptr, id);
 }
 
-TEST_F(ResourceParserTest, FilterProductsThatDontMatch) {
+TEST_F(ResourceParserTest, KeepAllProducts) {
     std::string input = R"EOF(
         <string name="foo" product="phone">hi</string>
         <string name="foo" product="no-sdcard">ho</string>
@@ -555,33 +544,26 @@
         <string name="bit" product="phablet">hoot</string>
         <string name="bot" product="default">yes</string>
     )EOF";
-    ASSERT_TRUE(testParse(input, { std::u16string(u"no-sdcard"), std::u16string(u"phablet") }));
+    ASSERT_TRUE(testParse(input));
 
-    String* fooStr = test::getValue<String>(&mTable, u"@string/foo");
-    ASSERT_NE(nullptr, fooStr);
-    EXPECT_EQ(StringPiece16(u"ho"), *fooStr->value);
-
-    EXPECT_NE(nullptr, test::getValue<String>(&mTable, u"@string/bar"));
-    EXPECT_NE(nullptr, test::getValue<String>(&mTable, u"@string/baz"));
-    EXPECT_NE(nullptr, test::getValue<String>(&mTable, u"@string/bit"));
-    EXPECT_NE(nullptr, test::getValue<String>(&mTable, u"@string/bot"));
-}
-
-TEST_F(ResourceParserTest, FilterProductsThatBothMatchInOrder) {
-    std::string input = R"EOF(
-        <string name="foo" product="phone">phone</string>
-        <string name="foo" product="default">default</string>
-    )EOF";
-    ASSERT_TRUE(testParse(input, { std::u16string(u"phone") }));
-
-    String* foo = test::getValue<String>(&mTable, u"@string/foo");
-    ASSERT_NE(nullptr, foo);
-    EXPECT_EQ(std::u16string(u"phone"), *foo->value);
-}
-
-TEST_F(ResourceParserTest, FailWhenProductFilterStripsOutAllVersionsOfResource) {
-    std::string input = "<string name=\"foo\" product=\"tablet\">hello</string>\n";
-    ASSERT_FALSE(testParse(input, { std::u16string(u"phone") }));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/foo",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 "phone"));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/foo",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 "no-sdcard"));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/bar",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 ""));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/baz",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 ""));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/bit",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 "phablet"));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<String>(&mTable, u"@string/bot",
+                                                                 ConfigDescription::defaultConfig(),
+                                                                 "default"));
 }
 
 TEST_F(ResourceParserTest, AutoIncrementIdsInPublicGroup) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 8a3d047..3e73be4 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -19,8 +19,6 @@
 #include "ResourceTable.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
-
-#include "util/Comparators.h"
 #include "util/Util.h"
 
 #include <algorithm>
@@ -124,6 +122,73 @@
     return entries.emplace(iter, new ResourceEntry(name))->get();
 }
 
+ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config) {
+    return findValue(config, StringPiece());
+}
+
+struct ConfigKey {
+    const ConfigDescription* config;
+    const StringPiece& product;
+};
+
+bool ltConfigKeyRef(const std::unique_ptr<ResourceConfigValue>& lhs, const ConfigKey& rhs) {
+    int cmp = lhs->config.compare(*rhs.config);
+    if (cmp == 0) {
+        cmp = StringPiece(lhs->product).compare(rhs.product);
+    }
+    return cmp < 0;
+}
+
+ResourceConfigValue* ResourceEntry::findValue(const ConfigDescription& config,
+                                              const StringPiece& product) {
+    auto iter = std::lower_bound(values.begin(), values.end(),
+                                 ConfigKey{ &config, product }, ltConfigKeyRef);
+    if (iter != values.end()) {
+        ResourceConfigValue* value = iter->get();
+        if (value->config == config && StringPiece(value->product) == product) {
+            return value;
+        }
+    }
+    return nullptr;
+}
+
+ResourceConfigValue* ResourceEntry::findOrCreateValue(const ConfigDescription& config,
+                                                      const StringPiece& product) {
+    auto iter = std::lower_bound(values.begin(), values.end(),
+                                 ConfigKey{ &config, product }, ltConfigKeyRef);
+    if (iter != values.end()) {
+        ResourceConfigValue* value = iter->get();
+        if (value->config == config && StringPiece(value->product) == product) {
+            return value;
+        }
+    }
+    ResourceConfigValue* newValue = values.insert(
+            iter, util::make_unique<ResourceConfigValue>(config, product))->get();
+    return newValue;
+}
+
+std::vector<ResourceConfigValue*> ResourceEntry::findAllValues(const ConfigDescription& config) {
+    std::vector<ResourceConfigValue*> results;
+
+    auto iter = values.begin();
+    for (; iter != values.end(); ++iter) {
+        ResourceConfigValue* value = iter->get();
+        if (value->config == config) {
+            results.push_back(value);
+            ++iter;
+            break;
+        }
+    }
+
+    for (; iter != values.end(); ++iter) {
+        ResourceConfigValue* value = iter->get();
+        if (value->config == config) {
+            results.push_back(value);
+        }
+    }
+    return results;
+}
+
 /**
  * The default handler for collisions. A return value of -1 means keep the
  * existing value, 0 means fail, and +1 means take the incoming value.
@@ -188,56 +253,69 @@
 static constexpr const char16_t* kValidNameChars = u"._-";
 static constexpr const char16_t* kValidNameMangledChars = u"._-$";
 
-bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
-                                std::unique_ptr<Value> value, IDiagnostics* 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,
+bool ResourceTable::addResource(const ResourceNameRef& name,
+                                const ConfigDescription& config,
+                                const StringPiece& product,
+                                std::unique_ptr<Value> value,
                                 IDiagnostics* diag) {
-    return addResourceImpl(name, resId, config, std::move(value), kValidNameChars,
+    return addResourceImpl(name, {}, config, product, std::move(value), kValidNameChars,
                            resolveValueCollision, diag);
 }
 
-bool ResourceTable::addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
-                                     const Source& source, const StringPiece16& path,
+bool ResourceTable::addResource(const ResourceNameRef& name,
+                                const ResourceId resId,
+                                const ConfigDescription& config,
+                                const StringPiece& product,
+                                std::unique_ptr<Value> value,
+                                IDiagnostics* diag) {
+    return addResourceImpl(name, resId, config, product, 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,
+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,
-                           conflictResolver, diag);
+    return addResourceImpl(name, ResourceId{}, config, StringPiece{}, std::move(fileRef),
+                           kValidNameChars, conflictResolver, diag);
 }
 
 bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
                                             const ConfigDescription& config,
+                                            const StringPiece& product,
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
-    return addResourceImpl(name, ResourceId{}, config, std::move(value), kValidNameMangledChars,
-                           resolveValueCollision, diag);
+    return addResourceImpl(name, ResourceId{}, config, product, std::move(value),
+                           kValidNameMangledChars, resolveValueCollision, diag);
 }
 
 bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
                                             const ResourceId id,
                                             const ConfigDescription& config,
+                                            const StringPiece& product,
                                             std::unique_ptr<Value> value,
                                             IDiagnostics* diag) {
-    return addResourceImpl(name, id, config, std::move(value), kValidNameMangledChars,
+    return addResourceImpl(name, id, config, product, std::move(value), kValidNameMangledChars,
                            resolveValueCollision, diag);
 }
 
 bool ResourceTable::addResourceImpl(const ResourceNameRef& name,
                                     const ResourceId resId,
                                     const ConfigDescription& config,
+                                    const StringPiece& product,
                                     std::unique_ptr<Value> value,
                                     const char16_t* validChars,
                                     std::function<int(Value*,Value*)> conflictResolver,
@@ -298,21 +376,21 @@
         return false;
     }
 
-    const auto endIter = entry->values.end();
-    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) });
+    ResourceConfigValue* configValue = entry->findOrCreateValue(config, product);
+    if (!configValue->value) {
+        // Resource does not exist, add it now.
+        configValue->value = std::move(value);
+
     } else {
-        int collisionResult = conflictResolver(iter->value.get(), value.get());
+        int collisionResult = conflictResolver(configValue->value.get(), value.get());
         if (collisionResult > 0) {
             // Take the incoming value.
-            iter->value = std::move(value);
+            configValue->value = std::move(value);
         } else if (collisionResult == 0) {
             diag->error(DiagMessage(value->getSource())
                         << "duplicate value for resource '" << name << "' "
                         << "with config '" << config << "'");
-            diag->error(DiagMessage(iter->value->getSource())
+            diag->error(DiagMessage(configValue->value->getSource())
                         << "resource previously defined here");
             return false;
         }
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 6b7b07e..8ffff1f 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -24,9 +24,12 @@
 #include "Source.h"
 #include "StringPool.h"
 
+#include <android-base/macros.h>
+#include <map>
 #include <memory>
 #include <string>
 #include <tuple>
+#include <unordered_map>
 #include <vector>
 
 namespace aapt {
@@ -46,19 +49,36 @@
     std::u16string comment;
 };
 
-/**
- * Represents a value defined for a given configuration.
- */
-struct ResourceConfigValue {
-    ConfigDescription config;
+class ResourceConfigValue {
+public:
+    /**
+     * The configuration for which this value is defined.
+     */
+    const ConfigDescription config;
+
+    /**
+     * The product for which this value is defined.
+     */
+    const std::string product;
+
+    /**
+     * The actual Value.
+     */
     std::unique_ptr<Value> value;
+
+    ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) :
+            config(config), product(product.toString()) { }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
 };
 
 /**
  * Represents a resource entry, which may have
  * varying values for each defined configuration.
  */
-struct ResourceEntry {
+class ResourceEntry {
+public:
     /**
      * The name of the resource. Immutable, as
      * this determines the order of this resource
@@ -72,24 +92,33 @@
     Maybe<uint16_t> id;
 
     /**
-     * Whether this resource is public (and must maintain the same
-     * entry ID across builds).
+     * Whether this resource is public (and must maintain the same entry ID across builds).
      */
     Symbol symbolStatus;
 
     /**
      * The resource's values for each configuration.
      */
-    std::vector<ResourceConfigValue> values;
+    std::vector<std::unique_ptr<ResourceConfigValue>> values;
 
     ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
+
+    ResourceConfigValue* findValue(const ConfigDescription& config);
+    ResourceConfigValue* findValue(const ConfigDescription& config, const StringPiece& product);
+    ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
+                                           const StringPiece& product);
+    std::vector<ResourceConfigValue*> findAllValues(const ConfigDescription& config);
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
 };
 
 /**
  * Represents a resource type, which holds entries defined
  * for this type.
  */
-struct ResourceTableType {
+class ResourceTableType {
+public:
     /**
      * The logical type of resource (string, drawable, layout, etc.).
      */
@@ -114,8 +143,10 @@
     explicit ResourceTableType(const ResourceType type) : type(type) { }
 
     ResourceEntry* findEntry(const StringPiece16& name);
-
     ResourceEntry* findOrCreateEntry(const StringPiece16& name);
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
 };
 
 enum class PackageType {
@@ -125,16 +156,20 @@
     Dynamic
 };
 
-struct ResourceTablePackage {
+class ResourceTablePackage {
+public:
     PackageType type = PackageType::App;
     Maybe<uint8_t> id;
     std::u16string name;
 
     std::vector<std::unique_ptr<ResourceTableType>> types;
 
+    ResourceTablePackage() = default;
     ResourceTableType* findType(ResourceType type);
-
     ResourceTableType* findOrCreateType(const ResourceType type);
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
 };
 
 /**
@@ -144,8 +179,6 @@
 class ResourceTable {
 public:
     ResourceTable() = default;
-    ResourceTable(const ResourceTable&) = delete;
-    ResourceTable& operator=(const ResourceTable&) = delete;
 
     /**
      * When a collision of resources occurs, this method decides which value to keep.
@@ -155,38 +188,59 @@
      */
     static int resolveValueCollision(Value* existing, Value* incoming);
 
-    bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
-                     std::unique_ptr<Value> value, IDiagnostics* diag);
-
-    bool addResource(const ResourceNameRef& name, const ResourceId resId,
-                     const ConfigDescription& config, std::unique_ptr<Value> value,
+    bool addResource(const ResourceNameRef& name,
+                     const ConfigDescription& config,
+                     const StringPiece& product,
+                     std::unique_ptr<Value> value,
                      IDiagnostics* diag);
 
-    bool addFileReference(const ResourceNameRef& name, const ConfigDescription& config,
-                          const Source& source, const StringPiece16& path,
+    bool addResource(const ResourceNameRef& name,
+                     const ResourceId resId,
+                     const ConfigDescription& config,
+                     const StringPiece& product,
+                     std::unique_ptr<Value> value,
+                     IDiagnostics* diag);
+
+    bool addFileReference(const ResourceNameRef& name,
+                          const ConfigDescription& config,
+                          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);
+    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
      * when loading resources from an existing binary resource table that may have mangled
      * names.
      */
-    bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
-                                 std::unique_ptr<Value> value, IDiagnostics* diag);
-
-    bool addResourceAllowMangled(const ResourceNameRef& name, const ResourceId id,
-                                 const ConfigDescription& config, std::unique_ptr<Value> value,
+    bool addResourceAllowMangled(const ResourceNameRef& name,
+                                 const ConfigDescription& config,
+                                 const StringPiece& product,
+                                 std::unique_ptr<Value> value,
                                  IDiagnostics* diag);
 
-    bool setSymbolState(const ResourceNameRef& name, const ResourceId resId,
-                        const Symbol& symbol, IDiagnostics* diag);
+    bool addResourceAllowMangled(const ResourceNameRef& name,
+                                 const ResourceId id,
+                                 const ConfigDescription& config,
+                                 const StringPiece& product,
+                                 std::unique_ptr<Value> value,
+                                 IDiagnostics* diag);
 
-    bool setSymbolStateAllowMangled(const ResourceNameRef& name, const ResourceId resId,
-                                    const Symbol& symbol, IDiagnostics* diag);
+    bool setSymbolState(const ResourceNameRef& name,
+                        const ResourceId resId,
+                        const Symbol& symbol,
+                        IDiagnostics* diag);
+
+    bool setSymbolStateAllowMangled(const ResourceNameRef& name,
+                                    const ResourceId resId,
+                                    const Symbol& symbol,
+                                    IDiagnostics* diag);
 
     struct SearchResult {
         ResourceTablePackage* package;
@@ -229,13 +283,19 @@
     bool addResourceImpl(const ResourceNameRef& name,
                          ResourceId resId,
                          const ConfigDescription& config,
+                         const StringPiece& product,
                          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);
+    bool setSymbolStateImpl(const ResourceNameRef& name,
+                            ResourceId resId,
+                            const Symbol& symbol,
+                            const char16_t* validChars,
+                            IDiagnostics* diag);
+
+    DISALLOW_COPY_AND_ASSIGN(ResourceTable);
 };
 
 } // namespace aapt
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 42508fe..180bd11 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -43,13 +43,13 @@
 
     EXPECT_FALSE(table.addResource(
             ResourceNameRef(u"android", ResourceType::kId, u"hey,there"),
-            ConfigDescription{},
+            ConfigDescription{}, "",
             test::ValueBuilder<Id>().setSource("test.xml", 21u).build(),
             &mDiagnostics));
 
     EXPECT_FALSE(table.addResource(
             ResourceNameRef(u"android", ResourceType::kId, u"hey:there"),
-            ConfigDescription{},
+            ConfigDescription{}, "",
             test::ValueBuilder<Id>().setSource("test.xml", 21u).build(),
             &mDiagnostics));
 }
@@ -59,6 +59,7 @@
 
     EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/id"),
                                   ConfigDescription{},
+                                  "",
                                   test::ValueBuilder<Id>()
                                           .setSource("test/path/file.xml", 23u).build(),
                                   &mDiagnostics));
@@ -76,24 +77,28 @@
     EXPECT_TRUE(table.addResource(
             test::parseNameOrDie(u"@android:attr/layout_width"),
             config,
+            "",
             test::ValueBuilder<Id>().setSource("test/path/file.xml", 10u).build(),
             &mDiagnostics));
 
     EXPECT_TRUE(table.addResource(
             test::parseNameOrDie(u"@android:attr/id"),
             config,
+            "",
             test::ValueBuilder<Id>().setSource("test/path/file.xml", 12u).build(),
             &mDiagnostics));
 
     EXPECT_TRUE(table.addResource(
             test::parseNameOrDie(u"@android:string/ok"),
             config,
+            "",
             test::ValueBuilder<Id>().setSource("test/path/file.xml", 14u).build(),
             &mDiagnostics));
 
     EXPECT_TRUE(table.addResource(
             test::parseNameOrDie(u"@android:string/ok"),
             languageConfig,
+            "",
             test::ValueBuilder<BinaryPrimitive>(android::Res_value{})
                     .setSource("test/path/file.xml", 20u)
                     .build(),
@@ -110,18 +115,49 @@
     ResourceTable table;
 
     ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/foo"), ConfigDescription{},
-                                  util::make_unique<Attribute>(true), &mDiagnostics));
+                                  "", util::make_unique<Attribute>(true), &mDiagnostics));
 
     Attribute* attr = test::getValue<Attribute>(&table, u"@android:attr/foo");
     ASSERT_NE(nullptr, attr);
     EXPECT_TRUE(attr->isWeak());
 
     ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/foo"), ConfigDescription{},
-                                  util::make_unique<Attribute>(false), &mDiagnostics));
+                                  "", util::make_unique<Attribute>(false), &mDiagnostics));
 
     attr = test::getValue<Attribute>(&table, u"@android:attr/foo");
     ASSERT_NE(nullptr, attr);
     EXPECT_FALSE(attr->isWeak());
 }
 
+TEST_F(ResourceTableTest, ProductVaryingValues) {
+    ResourceTable table;
+
+    EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/foo"),
+                                  test::parseConfigOrDie("land"),
+                                  "tablet",
+                                  util::make_unique<Id>(),
+                                  &mDiagnostics));
+    EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/foo"),
+                                  test::parseConfigOrDie("land"),
+                                  "phone",
+                                  util::make_unique<Id>(),
+                                  &mDiagnostics));
+
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/foo",
+                                                             test::parseConfigOrDie("land"),
+                                                             "tablet"));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/foo",
+                                                             test::parseConfigOrDie("land"),
+                                                             "phone"));
+
+    Maybe<ResourceTable::SearchResult> sr = table.findResource(
+            test::parseNameOrDie(u"@android:string/foo"));
+    AAPT_ASSERT_TRUE(sr);
+    std::vector<ResourceConfigValue*> values = sr.value().entry->findAllValues(
+            test::parseConfigOrDie("land"));
+    ASSERT_EQ(2u, values.size());
+    EXPECT_EQ(std::string("phone"), values[0]->product);
+    EXPECT_EQ(std::string("tablet"), values[1]->product);
+}
+
 } // namespace aapt
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 07f62af..74c48b0 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -51,6 +51,10 @@
 }
 
 bool parseResourceName(const StringPiece16& str, ResourceNameRef* outRef, bool* outPrivate) {
+    if (str.empty()) {
+        return false;
+    }
+
     size_t offset = 0;
     bool priv = false;
     if (str.data()[0] == u'*') {
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 64ca971..a0fbcc6 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -45,7 +45,8 @@
  * `outResource` set to the parsed resource name and `outPrivate` set to true if a '*' prefix
  * was present.
  */
-bool parseResourceName(const StringPiece16& str, ResourceNameRef* outResource, bool* outPrivate);
+bool parseResourceName(const StringPiece16& str, ResourceNameRef* outResource,
+                       bool* outPrivate = nullptr);
 
 /*
  * Returns true if the string was parsed as a reference (@[+][package:]type/name), with
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index c9f93e1..7425f97 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -58,6 +58,8 @@
     EXPECT_TRUE(ResourceUtils::parseResourceName(u"*android:color/foo", &actual, &actualPriv));
     EXPECT_EQ(ResourceNameRef(u"android", ResourceType::kColor, u"foo"), actual);
     EXPECT_TRUE(actualPriv);
+
+    EXPECT_FALSE(ResourceUtils::parseResourceName(StringPiece16(), &actual, &actualPriv));
 }
 
 TEST(ResourceUtilsTest, ParseReferenceWithNoPackage) {
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index b93e6d8..ab9c792 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -19,7 +19,6 @@
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
-#include "flatten/ResourceTypeExtensions.h"
 
 #include <androidfw/ResourceTypes.h>
 #include <limits>
@@ -47,7 +46,7 @@
 }
 
 bool RawString::flatten(android::Res_value* outValue) const {
-    outValue->dataType = ExtendedTypes::TYPE_RAW_STRING;
+    outValue->dataType = android::Res_value::TYPE_STRING;
     outValue->data = util::hostToDevice32(static_cast<uint32_t>(value.getIndex()));
     return true;
 }
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 8e317db..dc2e28e 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -154,8 +154,8 @@
     bool privateReference = false;
 
     Reference();
-    Reference(const ResourceNameRef& n, Type type = Type::kResource);
-    Reference(const ResourceId& i, Type type = Type::kResource);
+    explicit Reference(const ResourceNameRef& n, Type type = Type::kResource);
+    explicit Reference(const ResourceId& i, Type type = Type::kResource);
 
     bool flatten(android::Res_value* outValue) const override;
     Reference* clone(StringPool* newPool) const override;
diff --git a/tools/aapt2/ValueVisitor.h b/tools/aapt2/ValueVisitor.h
index 94042e3..ea2aa55 100644
--- a/tools/aapt2/ValueVisitor.h
+++ b/tools/aapt2/ValueVisitor.h
@@ -18,6 +18,7 @@
 #define AAPT_VALUE_VISITOR_H
 
 #include "ResourceValues.h"
+#include "ResourceTable.h"
 
 namespace aapt {
 
@@ -140,6 +141,23 @@
     return visitor.value;
 }
 
+
+inline void visitAllValuesInPackage(ResourceTablePackage* pkg, RawValueVisitor* visitor) {
+    for (auto& type : pkg->types) {
+        for (auto& entry : type->entries) {
+            for (auto& configValue : entry->values) {
+                configValue->value->accept(visitor);
+            }
+        }
+    }
+}
+
+inline void visitAllValuesInTable(ResourceTable* table, RawValueVisitor* visitor) {
+    for (auto& pkg : table->packages) {
+        visitAllValuesInPackage(pkg.get(), visitor);
+    }
+}
+
 } // namespace aapt
 
 #endif // AAPT_VALUE_VISITOR_H
diff --git a/tools/aapt2/compile/Compile.cpp b/tools/aapt2/compile/Compile.cpp
index 689ace6..0dd8e18 100644
--- a/tools/aapt2/compile/Compile.cpp
+++ b/tools/aapt2/compile/Compile.cpp
@@ -24,15 +24,17 @@
 #include "compile/PseudolocaleGenerator.h"
 #include "compile/XmlIdCollector.h"
 #include "flatten/Archive.h"
-#include "flatten/FileExportWriter.h"
-#include "flatten/TableFlattener.h"
 #include "flatten/XmlFlattener.h"
+#include "proto/ProtoSerialize.h"
 #include "util/Files.h"
 #include "util/Maybe.h"
 #include "util/Util.h"
 #include "xml/XmlDom.h"
 #include "xml/XmlPullParser.h"
 
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/io/coded_stream.h>
+
 #include <dirent.h>
 #include <fstream>
 #include <string>
@@ -105,7 +107,6 @@
 struct CompileOptions {
     std::string outputPath;
     Maybe<std::string> resDir;
-    std::vector<std::u16string> products;
     bool pseudolocalize = false;
     bool legacyMode = false;
     bool verbose = false;
@@ -196,7 +197,6 @@
         xml::XmlPullParser xmlParser(fin);
 
         ResourceParserOptions parserOptions;
-        parserOptions.products = options.products;
         parserOptions.errorOnPositionalArguments = !options.legacyMode;
 
         // If the filename includes donottranslate, then the default translatable is false.
@@ -232,34 +232,95 @@
         }
     }
 
-    // Assign IDs to prepare the table for flattening.
-    IdAssigner idAssigner;
-    if (!idAssigner.consume(context, &table)) {
-        return false;
-    }
-
-    // Flatten the table.
-    BigBuffer buffer(1024);
-    TableFlattenerOptions tableFlattenerOptions;
-    tableFlattenerOptions.useExtendedChunks = true;
-    TableFlattener flattener(&buffer, tableFlattenerOptions);
-    if (!flattener.consume(context, &table)) {
-        return false;
-    }
-
+    // Create the file/zip entry.
     if (!writer->startEntry(outputPath, 0)) {
         context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
         return false;
     }
 
-    if (writer->writeEntry(buffer)) {
-        if (writer->finishEntry()) {
-            return true;
+    std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(&table);
+
+    // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream interface.
+    {
+        google::protobuf::io::CopyingOutputStreamAdaptor adaptor(writer);
+
+        if (!pbTable->SerializeToZeroCopyStream(&adaptor)) {
+            context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
+            return false;
         }
     }
 
-    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-    return false;
+    if (!writer->finishEntry()) {
+        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to finish entry");
+        return false;
+    }
+    return true;
+}
+
+static bool writeHeaderAndBufferToWriter(const StringPiece& outputPath, const ResourceFile& file,
+                                         const BigBuffer& buffer, IArchiveWriter* writer,
+                                         IDiagnostics* diag) {
+    // Start the entry so we can write the header.
+    if (!writer->startEntry(outputPath, 0)) {
+        diag->error(DiagMessage(outputPath) << "failed to open file");
+        return false;
+    }
+
+    // Create the header.
+    std::unique_ptr<pb::CompiledFile> pbCompiledFile = serializeCompiledFileToPb(file);
+
+    {
+        // The stream must be destroyed before we finish the entry, or else
+        // some data won't be flushed.
+        // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream
+        // interface.
+        google::protobuf::io::CopyingOutputStreamAdaptor adaptor(writer);
+        CompiledFileOutputStream outputStream(&adaptor, pbCompiledFile.get());
+        for (const BigBuffer::Block& block : buffer) {
+            if (!outputStream.Write(block.buffer.get(), block.size)) {
+                diag->error(DiagMessage(outputPath) << "failed to write data");
+                return false;
+            }
+        }
+    }
+
+    if (!writer->finishEntry()) {
+        diag->error(DiagMessage(outputPath) << "failed to finish writing data");
+        return false;
+    }
+    return true;
+}
+
+static bool writeHeaderAndMmapToWriter(const StringPiece& outputPath, const ResourceFile& file,
+                                       const android::FileMap& map, IArchiveWriter* writer,
+                                       IDiagnostics* diag) {
+    // Start the entry so we can write the header.
+    if (!writer->startEntry(outputPath, 0)) {
+        diag->error(DiagMessage(outputPath) << "failed to open file");
+        return false;
+    }
+
+    // Create the header.
+    std::unique_ptr<pb::CompiledFile> pbCompiledFile = serializeCompiledFileToPb(file);
+
+    {
+        // The stream must be destroyed before we finish the entry, or else
+        // some data won't be flushed.
+        // Wrap our IArchiveWriter with an adaptor that implements the ZeroCopyOutputStream
+        // interface.
+        google::protobuf::io::CopyingOutputStreamAdaptor adaptor(writer);
+        CompiledFileOutputStream outputStream(&adaptor, pbCompiledFile.get());
+        if (!outputStream.Write(map.getDataPtr(), map.getDataLength())) {
+            diag->error(DiagMessage(outputPath) << "failed to write data");
+            return false;
+        }
+    }
+
+    if (!writer->finishEntry()) {
+        diag->error(DiagMessage(outputPath) << "failed to finish writing data");
+        return false;
+    }
+    return true;
 }
 
 static bool compileXml(IAaptContext* context, const CompileOptions& options,
@@ -267,7 +328,6 @@
                        const std::string& outputPath) {
 
     std::unique_ptr<xml::XmlResource> xmlRes;
-
     {
         std::ifstream fin(pathData.source.path, std::ifstream::binary);
         if (!fin) {
@@ -295,30 +355,18 @@
     xmlRes->file.source = pathData.source;
 
     BigBuffer buffer(1024);
-    ChunkWriter fileExportWriter = wrapBufferWithFileExportHeader(&buffer, &xmlRes->file);
-
     XmlFlattenerOptions xmlFlattenerOptions;
     xmlFlattenerOptions.keepRawValues = true;
-    XmlFlattener flattener(fileExportWriter.getBuffer(), xmlFlattenerOptions);
+    XmlFlattener flattener(&buffer, xmlFlattenerOptions);
     if (!flattener.consume(context, xmlRes.get())) {
         return false;
     }
 
-    fileExportWriter.finish();
-
-    if (!writer->startEntry(outputPath, 0)) {
-        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
+    if (!writeHeaderAndBufferToWriter(outputPath, xmlRes->file, buffer, writer,
+                                      context->getDiagnostics())) {
         return false;
     }
-
-    if (writer->writeEntry(buffer)) {
-        if (writer->finishEntry()) {
-            return true;
-        }
-    }
-
-    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-    return false;
+    return true;
 }
 
 static bool compilePng(IAaptContext* context, const CompileOptions& options,
@@ -330,8 +378,6 @@
     resFile.config = pathData.config;
     resFile.source = pathData.source;
 
-    ChunkWriter fileExportWriter = wrapBufferWithFileExportHeader(&buffer, &resFile);
-
     {
         std::ifstream fin(pathData.source.path, std::ifstream::binary);
         if (!fin) {
@@ -340,26 +386,16 @@
         }
 
         Png png(context->getDiagnostics());
-        if (!png.process(pathData.source, &fin, fileExportWriter.getBuffer(), {})) {
+        if (!png.process(pathData.source, &fin, &buffer, {})) {
             return false;
         }
     }
 
-    fileExportWriter.finish();
-
-    if (!writer->startEntry(outputPath, 0)) {
-        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
+    if (!writeHeaderAndBufferToWriter(outputPath, resFile, buffer, writer,
+                                      context->getDiagnostics())) {
         return false;
     }
-
-    if (writer->writeEntry(buffer)) {
-        if (writer->finishEntry()) {
-            return true;
-        }
-    }
-
-    context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-    return false;
+    return true;
 }
 
 static bool compileFile(IAaptContext* context, const CompileOptions& options,
@@ -371,8 +407,6 @@
     resFile.config = pathData.config;
     resFile.source = pathData.source;
 
-    ChunkWriter fileExportWriter = wrapBufferWithFileExportHeader(&buffer, &resFile);
-
     std::string errorStr;
     Maybe<android::FileMap> f = file::mmapPath(pathData.source.path, &errorStr);
     if (!f) {
@@ -380,35 +414,10 @@
         return false;
     }
 
-    if (!writer->startEntry(outputPath, 0)) {
-        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to open");
+    if (!writeHeaderAndMmapToWriter(outputPath, resFile, f.value(), writer,
+                                    context->getDiagnostics())) {
         return false;
     }
-
-    // Manually set the size and don't call finish(). This is because we are not copying from
-    // the buffer the entire file.
-    fileExportWriter.getChunkHeader()->size =
-            util::hostToDevice32(buffer.size() + f.value().getDataLength());
-
-    if (!writer->writeEntry(buffer)) {
-        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-        return false;
-    }
-
-    // Only write if we have something to write. This is because mmap fails with length of 0,
-    // but we still want to compile the file to get the resource ID.
-    if (f.value().getDataPtr() && f.value().getDataLength() > 0) {
-        if (!writer->writeEntry(f.value().getDataPtr(), f.value().getDataLength())) {
-            context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-            return false;
-        }
-    }
-
-    if (!writer->finishEntry()) {
-        context->getDiagnostics()->error(DiagMessage(outputPath) << "failed to write");
-        return false;
-    }
-
     return true;
 }
 
@@ -446,11 +455,8 @@
 int compile(const std::vector<StringPiece>& args) {
     CompileOptions options;
 
-    Maybe<std::string> productList;
     Flags flags = Flags()
             .requiredFlag("-o", "Output path", &options.outputPath)
-            .optionalFlag("--product", "Comma separated list of product types to compile",
-                          &productList)
             .optionalFlag("--dir", "Directory to scan for resources", &options.resDir)
             .optionalSwitch("--pseudo-localize", "Generate resources for pseudo-locales "
                             "(en-XA and ar-XB)", &options.pseudolocalize)
@@ -461,12 +467,6 @@
         return 1;
     }
 
-    if (productList) {
-        for (StringPiece part : util::tokenize<char>(productList.value(), ',')) {
-            options.products.push_back(util::utf8ToUtf16(part));
-        }
-    }
-
     CompileContext context;
     std::unique_ptr<IArchiveWriter> archiveWriter;
 
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index 80c6bbc..aa4a580 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -64,14 +64,12 @@
                     // Mark entry ID as taken.
                     if (!usedEntryIds.insert(entry->id.value()).second) {
                         // This ID existed before!
-                        ResourceNameRef nameRef =
-                                { package->name, type->type, entry->name };
-                        ResourceId takenId(package->id.value(), type->id.value(),
-                                           entry->id.value());
+                        ResourceNameRef nameRef(package->name, type->type, entry->name);
                         context->getDiagnostics()->error(DiagMessage()
                                                          << "resource '" << nameRef << "' "
-                                                         << "has duplicate ID '"
-                                                         << takenId << "'");
+                                                         << "has duplicate entry ID "
+                                                         << std::hex << (int) entry->id.value()
+                                                         << std::dec);
                         return false;
                     }
                 }
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index 2963d13..be26b52 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -19,7 +19,6 @@
 #include "ValueVisitor.h"
 #include "compile/PseudolocaleGenerator.h"
 #include "compile/Pseudolocalizer.h"
-#include "util/Comparators.h"
 
 namespace aapt {
 
@@ -208,10 +207,12 @@
     return modified;
 }
 
-void pseudolocalizeIfNeeded(std::vector<ResourceConfigValue>* configValues,
-                            Pseudolocalizer::Method method, StringPool* pool, Value* value) {
+void pseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
+                            ResourceConfigValue* originalValue,
+                            StringPool* pool,
+                            ResourceEntry* entry) {
     Visitor visitor(pool, method);
-    value->accept(&visitor);
+    originalValue->value->accept(&visitor);
 
     std::unique_ptr<Value> localizedValue;
     if (visitor.mValue) {
@@ -220,16 +221,18 @@
         localizedValue = std::move(visitor.mItem);
     }
 
-    if (localizedValue) {
-        ConfigDescription pseudolocalizedConfig = modifyConfigForPseudoLocale(ConfigDescription{},
-                                                                              method);
-        auto iter = std::lower_bound(configValues->begin(), configValues->end(),
-                                     pseudolocalizedConfig, cmp::lessThanConfig);
-        if (iter == configValues->end() || iter->config != pseudolocalizedConfig) {
-            // The pseudolocalized config doesn't exist, add it.
-            configValues->insert(iter, ResourceConfigValue{ pseudolocalizedConfig,
-                                                            std::move(localizedValue) });
-        }
+    if (!localizedValue) {
+        return;
+    }
+
+    ConfigDescription configWithAccent = modifyConfigForPseudoLocale(
+            originalValue->config, method);
+
+    ResourceConfigValue* newConfigValue = entry->findOrCreateValue(
+            configWithAccent, originalValue->product);
+    if (!newConfigValue->value) {
+        // Only use auto-generated pseudo-localization if none is defined.
+        newConfigValue->value = std::move(localizedValue);
     }
 }
 
@@ -239,18 +242,13 @@
     for (auto& package : table->packages) {
         for (auto& type : package->types) {
             for (auto& entry : type->entries) {
-                auto iter = std::lower_bound(entry->values.begin(), entry->values.end(),
-                                             ConfigDescription{}, cmp::lessThanConfig);
-                if (iter != entry->values.end() && iter->config == ConfigDescription{}) {
-                    // Only pseudolocalize the default configuration.
-
-                    // The iterator will be invalidated, so grab a pointer to the value.
-                    Value* originalValue = iter->value.get();
-
-                    pseudolocalizeIfNeeded(&entry->values, Pseudolocalizer::Method::kAccent,
-                                           &table->stringPool, originalValue);
-                    pseudolocalizeIfNeeded(&entry->values, Pseudolocalizer::Method::kBidi,
-                                           &table->stringPool, originalValue);
+                std::vector<ResourceConfigValue*> values = entry->findAllValues(
+                        ConfigDescription::defaultConfig());
+                for (ResourceConfigValue* value : values) {
+                    pseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value,
+                                           &table->stringPool, entry.get());
+                    pseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value,
+                                           &table->stringPool, entry.get());
                 }
             }
         }
diff --git a/tools/aapt2/dump/Dump.cpp b/tools/aapt2/dump/Dump.cpp
new file mode 100644
index 0000000..915fae8
--- /dev/null
+++ b/tools/aapt2/dump/Dump.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Debug.h"
+#include "Diagnostics.h"
+#include "Flags.h"
+#include "process/IResourceTableConsumer.h"
+#include "proto/ProtoSerialize.h"
+#include "util/Files.h"
+#include "util/StringPiece.h"
+
+#include <vector>
+
+namespace aapt {
+
+//struct DumpOptions {
+//
+//};
+
+void dumpCompiledFile(const pb::CompiledFile& pbFile, const void* data, size_t len,
+                      const Source& source, IAaptContext* context) {
+    std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(pbFile, source,
+                                                                       context->getDiagnostics());
+    if (!file) {
+        return;
+    }
+
+    std::cout << "Resource: " << file->name << "\n"
+              << "Config:   " << file->config << "\n"
+              << "Source:   " << file->source << "\n";
+}
+
+void dumpCompiledTable(const pb::ResourceTable& pbTable, const Source& source,
+                       IAaptContext* context) {
+    std::unique_ptr<ResourceTable> table = deserializeTableFromPb(pbTable, source,
+                                                                  context->getDiagnostics());
+    if (!table) {
+        return;
+    }
+
+    Debug::printTable(table.get());
+}
+
+void tryDumpFile(IAaptContext* context, const std::string& filePath) {
+    std::string err;
+    Maybe<android::FileMap> file = file::mmapPath(filePath, &err);
+    if (!file) {
+        context->getDiagnostics()->error(DiagMessage(filePath) << err);
+        return;
+    }
+
+    android::FileMap* fileMap = &file.value();
+
+    // Try as a compiled table.
+    pb::ResourceTable pbTable;
+    if (pbTable.ParseFromArray(fileMap->getDataPtr(), fileMap->getDataLength())) {
+        dumpCompiledTable(pbTable, Source(filePath), context);
+        return;
+    }
+
+    // Try as a compiled file.
+    CompiledFileInputStream input(fileMap->getDataPtr(), fileMap->getDataLength());
+    if (const pb::CompiledFile* pbFile = input.CompiledFile()) {
+       dumpCompiledFile(*pbFile, input.data(), input.size(), Source(filePath), context);
+       return;
+    }
+}
+
+class DumpContext : public IAaptContext {
+public:
+    IDiagnostics* getDiagnostics() override {
+        return &mDiagnostics;
+    }
+
+    NameMangler* getNameMangler() override {
+        abort();
+        return nullptr;
+    }
+
+    StringPiece16 getCompilationPackage() override {
+        return {};
+    }
+
+    uint8_t getPackageId() override {
+        return 0;
+    }
+
+    ISymbolTable* getExternalSymbols() override {
+        abort();
+        return nullptr;
+    }
+
+private:
+    StdErrDiagnostics mDiagnostics;
+};
+
+/**
+ * Entry point for dump command.
+ */
+int dump(const std::vector<StringPiece>& args) {
+    //DumpOptions options;
+    Flags flags = Flags();
+    if (!flags.parse("aapt2 dump", args, &std::cerr)) {
+        return 1;
+    }
+
+    DumpContext context;
+
+    for (const std::string& arg : flags.getArgs()) {
+        tryDumpFile(&context, arg);
+    }
+    return 0;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/flatten/Archive.h b/tools/aapt2/flatten/Archive.h
index 6da1d2a..34c10ad 100644
--- a/tools/aapt2/flatten/Archive.h
+++ b/tools/aapt2/flatten/Archive.h
@@ -22,6 +22,7 @@
 #include "util/Files.h"
 #include "util/StringPiece.h"
 
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <fstream>
 #include <memory>
 #include <string>
@@ -40,13 +41,18 @@
     size_t uncompressedSize;
 };
 
-struct IArchiveWriter {
+struct IArchiveWriter : public google::protobuf::io::CopyingOutputStream {
     virtual ~IArchiveWriter() = default;
 
     virtual bool startEntry(const StringPiece& path, uint32_t flags) = 0;
     virtual bool writeEntry(const BigBuffer& buffer) = 0;
     virtual bool writeEntry(const void* data, size_t len) = 0;
     virtual bool finishEntry() = 0;
+
+    // CopyingOutputStream implementations.
+    bool Write(const void* buffer, int size) override {
+        return writeEntry(buffer, size);
+    }
 };
 
 std::unique_ptr<IArchiveWriter> createDirectoryArchiveWriter(IDiagnostics* diag,
diff --git a/tools/aapt2/flatten/FileExportWriter.h b/tools/aapt2/flatten/FileExportWriter.h
deleted file mode 100644
index 7688fa7..0000000
--- a/tools/aapt2/flatten/FileExportWriter.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AAPT_FLATTEN_FILEEXPORTWRITER_H
-#define AAPT_FLATTEN_FILEEXPORTWRITER_H
-
-#include "StringPool.h"
-
-#include "flatten/ResourceTypeExtensions.h"
-#include "flatten/ChunkWriter.h"
-#include "process/IResourceTableConsumer.h"
-#include "util/BigBuffer.h"
-#include "util/Util.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <utils/misc.h>
-
-namespace aapt {
-
-static ChunkWriter wrapBufferWithFileExportHeader(BigBuffer* buffer, ResourceFile* res) {
-    ChunkWriter fileExportWriter(buffer);
-    FileExport_header* fileExport = fileExportWriter.startChunk<FileExport_header>(
-            RES_FILE_EXPORT_TYPE);
-
-    ExportedSymbol* symbolRefs = nullptr;
-    if (!res->exportedSymbols.empty()) {
-        symbolRefs = fileExportWriter.nextBlock<ExportedSymbol>(
-                res->exportedSymbols.size());
-    }
-    fileExport->exportedSymbolCount = util::hostToDevice32(res->exportedSymbols.size());
-
-    StringPool symbolExportPool;
-    memcpy(fileExport->magic, "AAPT", NELEM(fileExport->magic));
-    fileExport->config = res->config;
-    fileExport->config.swapHtoD();
-    fileExport->name.index = util::hostToDevice32(symbolExportPool.makeRef(res->name.toString())
-                                                  .getIndex());
-    fileExport->source.index = util::hostToDevice32(symbolExportPool.makeRef(util::utf8ToUtf16(
-            res->source.path)).getIndex());
-
-    for (const SourcedResourceName& name : res->exportedSymbols) {
-        symbolRefs->name.index = util::hostToDevice32(symbolExportPool.makeRef(name.name.toString())
-                                                      .getIndex());
-        symbolRefs->line = util::hostToDevice32(name.line);
-        symbolRefs++;
-    }
-
-    StringPool::flattenUtf16(fileExportWriter.getBuffer(), symbolExportPool);
-    return fileExportWriter;
-}
-
-} // namespace aapt
-
-#endif /* AAPT_FLATTEN_FILEEXPORTWRITER_H */
diff --git a/tools/aapt2/flatten/FileExportWriter_test.cpp b/tools/aapt2/flatten/FileExportWriter_test.cpp
deleted file mode 100644
index 32fc203..0000000
--- a/tools/aapt2/flatten/FileExportWriter_test.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Resource.h"
-
-#include "flatten/FileExportWriter.h"
-#include "util/BigBuffer.h"
-#include "util/Util.h"
-
-#include "test/Common.h"
-
-#include <gtest/gtest.h>
-
-namespace aapt {
-
-TEST(FileExportWriterTest, FlattenResourceFileDataWithNoExports) {
-    ResourceFile resFile = {
-            test::parseNameOrDie(u"@android:layout/main.xml"),
-            test::parseConfigOrDie("sw600dp-v4"),
-            Source{ "res/layout/main.xml" },
-    };
-
-    BigBuffer buffer(1024);
-    ChunkWriter writer = wrapBufferWithFileExportHeader(&buffer, &resFile);
-    *writer.getBuffer()->nextBlock<uint32_t>() = 42u;
-    writer.finish();
-
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-
-    // There should be more data (string pool) besides the header and our data.
-    ASSERT_GT(buffer.size(), sizeof(FileExport_header) + sizeof(uint32_t));
-
-    // Write at the end of this chunk is our data.
-    uint32_t* val = (uint32_t*)(data.get() + buffer.size()) - 1;
-    EXPECT_EQ(*val, 42u);
-}
-
-} // namespace aapt
diff --git a/tools/aapt2/flatten/ResourceTypeExtensions.h b/tools/aapt2/flatten/ResourceTypeExtensions.h
index 02bff2c..3e20ad6 100644
--- a/tools/aapt2/flatten/ResourceTypeExtensions.h
+++ b/tools/aapt2/flatten/ResourceTypeExtensions.h
@@ -22,208 +22,6 @@
 namespace aapt {
 
 /**
- * New android::ResChunk_header types defined
- * for AAPT to use.
- *
- * TODO(adamlesinski): Consider reserving these
- * enums in androidfw/ResourceTypes.h to avoid
- * future collisions.
- */
-enum {
-    /**
-     * A chunk that contains an entire file that
-     * has been compiled.
-     */
-    RES_FILE_EXPORT_TYPE = 0x000c,
-
-    RES_TABLE_PUBLIC_TYPE = 0x000d,
-
-    /**
-     * A chunk that holds the string pool
-     * for source entries (path/to/source:line).
-     */
-    RES_TABLE_SOURCE_POOL_TYPE = 0x000e,
-
-    /**
-     * A chunk holding names of externally
-     * defined symbols and offsets to where
-     * they are referenced in the table.
-     */
-    RES_TABLE_SYMBOL_TABLE_TYPE = 0x000f,
-};
-
-/**
- * New resource types that are meant to only be used
- * by AAPT and will not end up on the device.
- */
-struct ExtendedTypes {
-    enum {
-        /**
-         * A raw string value that hasn't had its escape sequences
-         * processed nor whitespace removed.
-         */
-        TYPE_RAW_STRING = 0xfe,
-    };
-};
-
-/**
- * New types for a ResTable_map.
- */
-struct ExtendedResTableMapTypes {
-    enum {
-        /**
-         * Type that contains the source path of the next item in the map.
-         */
-        ATTR_SOURCE_PATH = Res_MAKEINTERNAL(0xffff),
-
-        /**
-         * Type that contains the source line of the next item in the map.
-         */
-        ATTR_SOURCE_LINE = Res_MAKEINTERNAL(0xfffe),
-
-        /**
-         * Type that contains the comment of the next item in the map.
-         */
-        ATTR_COMMENT = Res_MAKEINTERNAL(0xfffd)
-    };
-};
-
-/**
- * Followed by exportedSymbolCount ExportedSymbol structs, followed by the string pool.
- */
-struct FileExport_header {
-    android::ResChunk_header header;
-
-    /**
-     * MAGIC value. Must be 'AAPT' (0x41415054)
-     */
-    uint8_t magic[4];
-
-    /**
-     * Version of AAPT that built this file.
-     */
-    uint32_t version;
-
-    /**
-     * The resource name.
-     */
-    android::ResStringPool_ref name;
-
-    /**
-     * Configuration of this file.
-     */
-    android::ResTable_config config;
-
-    /**
-     * Original source path of this file.
-     */
-    android::ResStringPool_ref source;
-
-    /**
-     * Number of symbols exported by this file.
-     */
-    uint32_t exportedSymbolCount;
-};
-
-struct ExportedSymbol {
-    android::ResStringPool_ref name;
-    uint32_t line;
-};
-
-struct Public_header {
-    android::ResChunk_header header;
-
-    /**
-     * The ID of the type this structure refers to.
-     */
-    uint8_t typeId;
-
-    /**
-     * Reserved. Must be 0.
-     */
-    uint8_t res0;
-
-    /**
-     * Reserved. Must be 0.
-     */
-    uint16_t res1;
-
-    /**
-     * Number of public entries.
-     */
-    uint32_t count;
-};
-
-/**
- * A structure representing source data for a resource entry.
- * Appears after an android::ResTable_entry or android::ResTable_map_entry.
- *
- * TODO(adamlesinski): This causes some issues when runtime code checks
- * the size of an android::ResTable_entry. It assumes it is an
- * android::ResTable_map_entry if the size is bigger than an android::ResTable_entry
- * which may not be true if this structure is present.
- */
-struct ResTable_entry_source {
-    /**
-     * File path reference.
-     */
-    android::ResStringPool_ref path;
-
-    /**
-     * Line number this resource was defined on.
-     */
-    uint32_t line;
-
-    /**
-     * Comment string reference.
-     */
-    android::ResStringPool_ref comment;
-};
-
-struct Public_entry {
-    uint16_t entryId;
-
-    enum : uint16_t {
-        kUndefined = 0,
-        kPublic = 1,
-        kPrivate = 2,
-    };
-
-    uint16_t state;
-    android::ResStringPool_ref key;
-    ResTable_entry_source source;
-};
-
-/**
- * A chunk with type RES_TABLE_SYMBOL_TABLE_TYPE.
- * Following the header are count number of SymbolTable_entry
- * structures, followed by an android::ResStringPool_header.
- */
-struct SymbolTable_header {
-    android::ResChunk_header header;
-
-    /**
-     * Number of SymbolTable_entry structures following
-     * this header.
-     */
-    uint32_t count;
-};
-
-struct SymbolTable_entry {
-    /**
-     * Offset from the beginning of the resource table
-     * where the symbol entry is referenced.
-     */
-    uint32_t offset;
-
-    /**
-     * The index into the string pool where the name of this
-     * symbol exists.
-     */
-    android::ResStringPool_ref name;
-};
-
-/**
  * An alternative struct to use instead of ResTable_map_entry. This one is a standard_layout
  * struct.
  */
diff --git a/tools/aapt2/flatten/TableFlattener.cpp b/tools/aapt2/flatten/TableFlattener.cpp
index 26d7c2c..da81046 100644
--- a/tools/aapt2/flatten/TableFlattener.cpp
+++ b/tools/aapt2/flatten/TableFlattener.cpp
@@ -51,157 +51,49 @@
     dst[i] = 0;
 }
 
+static bool cmpStyleEntries(const Style::Entry& a, const Style::Entry& b) {
+   if (a.key.id) {
+       if (b.key.id) {
+           return a.key.id.value() < b.key.id.value();
+       }
+       return true;
+   } else if (!b.key.id) {
+       return a.key.name.value() < b.key.name.value();
+   }
+   return false;
+}
+
 struct FlatEntry {
     ResourceEntry* entry;
     Value* value;
 
     // The entry string pool index to the entry's name.
     uint32_t entryKey;
-
-    // The source string pool index to the source file path.
-    uint32_t sourcePathKey;
-    uint32_t sourceLine;
-
-    // The source string pool index to the comment.
-    uint32_t commentKey;
 };
 
-class SymbolWriter {
+class MapFlattenVisitor : public RawValueVisitor {
 public:
-    struct Entry {
-        StringPool::Ref name;
-        size_t offset;
-    };
-
-    std::vector<Entry> symbols;
-
-    explicit SymbolWriter(StringPool* pool) : mPool(pool) {
-    }
-
-    void addSymbol(const Reference& ref, size_t offset) {
-        const ResourceName& name = ref.name.value();
-        std::u16string fullName;
-        if (ref.privateReference) {
-            fullName += u"*";
-        }
-
-        if (!name.package.empty()) {
-            fullName += name.package + u":";
-        }
-        fullName += toString(name.type).toString() + u"/" + name.entry;
-        symbols.push_back(Entry{ mPool->makeRef(fullName), offset });
-    }
-
-    void shiftAllOffsets(size_t offset) {
-        for (Entry& entry : symbols) {
-            entry.offset += offset;
-        }
-    }
-
-private:
-    StringPool* mPool;
-};
-
-struct MapFlattenVisitor : public RawValueVisitor {
     using RawValueVisitor::visit;
 
-    SymbolWriter* mSymbols;
-    FlatEntry* mEntry;
-    BigBuffer* mBuffer;
-    StringPool* mSourcePool;
-    StringPool* mCommentPool;
-    bool mUseExtendedChunks;
-
-    size_t mEntryCount = 0;
-    const Reference* mParent = nullptr;
-
-    MapFlattenVisitor(SymbolWriter* symbols, FlatEntry* entry, BigBuffer* buffer,
-                      StringPool* sourcePool, StringPool* commentPool,
-                      bool useExtendedChunks) :
-            mSymbols(symbols), mEntry(entry), mBuffer(buffer), mSourcePool(sourcePool),
-            mCommentPool(commentPool), mUseExtendedChunks(useExtendedChunks) {
-    }
-
-    void flattenKey(Reference* key, ResTable_map* outEntry) {
-        if (!key->id || (key->privateReference && mUseExtendedChunks)) {
-            assert(key->name && "reference must have a name");
-
-            outEntry->name.ident = util::hostToDevice32(0);
-            mSymbols->addSymbol(*key, (mBuffer->size() - sizeof(ResTable_map)) +
-                                    offsetof(ResTable_map, name));
-        } else {
-            outEntry->name.ident = util::hostToDevice32(key->id.value().id);
-        }
-    }
-
-    void flattenValue(Item* value, ResTable_map* outEntry) {
-        bool privateRef = false;
-        if (Reference* ref = valueCast<Reference>(value)) {
-            privateRef = ref->privateReference && mUseExtendedChunks;
-            if (!ref->id || privateRef) {
-                assert(ref->name && "reference must have a name");
-
-                mSymbols->addSymbol(*ref, (mBuffer->size() - sizeof(ResTable_map)) +
-                                        offsetof(ResTable_map, value) + offsetof(Res_value, data));
-            }
-        }
-
-        bool result = value->flatten(&outEntry->value);
-        if (privateRef) {
-            outEntry->value.data = 0;
-        }
-        assert(result && "flatten failed");
-    }
-
-    void flattenEntry(Reference* key, Item* value) {
-        ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
-        flattenKey(key, outEntry);
-        flattenValue(value, outEntry);
-        outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
-        mEntryCount++;
-    }
-
-    void flattenMetaData(Value* value) {
-        if (!mUseExtendedChunks) {
-            return;
-        }
-
-        Reference key(ResourceId{ ExtendedResTableMapTypes::ATTR_SOURCE_PATH });
-        StringPool::Ref sourcePathRef = mSourcePool->makeRef(
-                util::utf8ToUtf16(value->getSource().path));
-        BinaryPrimitive val(Res_value::TYPE_INT_DEC,
-                            static_cast<uint32_t>(sourcePathRef.getIndex()));
-        flattenEntry(&key, &val);
-
-        if (value->getSource().line) {
-            key.id = ResourceId(ExtendedResTableMapTypes::ATTR_SOURCE_LINE);
-            val.value.data = static_cast<uint32_t>(value->getSource().line.value());
-            flattenEntry(&key, &val);
-        }
-
-        if (!value->getComment().empty()) {
-            key.id = ResourceId(ExtendedResTableMapTypes::ATTR_COMMENT);
-            StringPool::Ref commentRef = mCommentPool->makeRef(value->getComment());
-            val.value.data = static_cast<uint32_t>(commentRef.getIndex());
-            flattenEntry(&key, &val);
-        }
+    MapFlattenVisitor(ResTable_entry_ext* outEntry, BigBuffer* buffer) :
+            mOutEntry(outEntry), mBuffer(buffer) {
     }
 
     void visit(Attribute* attr) override {
         {
-            Reference key(ResourceId{ ResTable_map::ATTR_TYPE });
+            Reference key = Reference(ResTable_map::ATTR_TYPE);
             BinaryPrimitive val(Res_value::TYPE_INT_DEC, attr->typeMask);
             flattenEntry(&key, &val);
         }
 
         if (attr->minInt != std::numeric_limits<int32_t>::min()) {
-            Reference key(ResourceId{ ResTable_map::ATTR_MIN });
+            Reference key = Reference(ResTable_map::ATTR_MIN);
             BinaryPrimitive val(Res_value::TYPE_INT_DEC, static_cast<uint32_t>(attr->minInt));
             flattenEntry(&key, &val);
         }
 
         if (attr->maxInt != std::numeric_limits<int32_t>::max()) {
-            Reference key(ResourceId{ ResTable_map::ATTR_MAX });
+            Reference key = Reference(ResTable_map::ATTR_MAX);
             BinaryPrimitive val(Res_value::TYPE_INT_DEC, static_cast<uint32_t>(attr->maxInt));
             flattenEntry(&key, &val);
         }
@@ -212,22 +104,11 @@
         }
     }
 
-    static bool cmpStyleEntries(const Style::Entry& a, const Style::Entry& b) {
-        if (a.key.id) {
-            if (b.key.id) {
-                return a.key.id.value() < b.key.id.value();
-            }
-            return true;
-        } else if (!b.key.id) {
-            return a.key.name.value() < b.key.name.value();
-        }
-        return false;
-    }
-
     void visit(Style* style) override {
         if (style->parent) {
-            // Parents are treated a bit differently, so record the existence and move on.
-            mParent = &style->parent.value();
+            const Reference& parentRef = style->parent.value();
+            assert(parentRef.id && "parent has no ID");
+            mOutEntry->parent.ident = util::hostToDevice32(parentRef.id.value().id);
         }
 
         // Sort the style.
@@ -235,7 +116,6 @@
 
         for (Style::Entry& entry : style->entries) {
             flattenEntry(&entry.key, entry.value.get());
-            flattenMetaData(&entry.key);
         }
     }
 
@@ -243,8 +123,8 @@
         for (auto& attrRef : styleable->entries) {
             BinaryPrimitive val(Res_value{});
             flattenEntry(&attrRef, &val);
-            flattenMetaData(&attrRef);
         }
+
     }
 
     void visit(Array* array) override {
@@ -253,7 +133,6 @@
             flattenValue(item.get(), outEntry);
             outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
             mEntryCount++;
-            flattenMetaData(item.get());
         }
     }
 
@@ -297,18 +176,45 @@
 
             Reference key(q);
             flattenEntry(&key, plural->values[i].get());
-            flattenMetaData(plural->values[i].get());
         }
     }
+
+    /**
+     * Call this after visiting a Value. This will finish any work that
+     * needs to be done to prepare the entry.
+     */
+    void finish() {
+        mOutEntry->count = util::hostToDevice32(mEntryCount);
+    }
+
+private:
+    void flattenKey(Reference* key, ResTable_map* outEntry) {
+        assert(key->id && "key has no ID");
+        outEntry->name.ident = util::hostToDevice32(key->id.value().id);
+    }
+
+    void flattenValue(Item* value, ResTable_map* outEntry) {
+        bool result = value->flatten(&outEntry->value);
+        assert(result && "flatten failed");
+    }
+
+    void flattenEntry(Reference* key, Item* value) {
+        ResTable_map* outEntry = mBuffer->nextBlock<ResTable_map>();
+        flattenKey(key, outEntry);
+        flattenValue(value, outEntry);
+        outEntry->value.size = util::hostToDevice16(sizeof(outEntry->value));
+        mEntryCount++;
+    }
+
+    ResTable_entry_ext* mOutEntry;
+    BigBuffer* mBuffer;
+    size_t mEntryCount = 0;
 };
 
 class PackageFlattener {
 public:
-    PackageFlattener(IDiagnostics* diag, TableFlattenerOptions options,
-                     ResourceTablePackage* package, SymbolWriter* symbolWriter,
-                     StringPool* sourcePool) :
-            mDiag(diag), mOptions(options), mPackage(package), mSymbols(symbolWriter),
-            mSourcePool(sourcePool) {
+    PackageFlattener(IDiagnostics* diag, ResourceTablePackage* package) :
+            mDiag(diag), mPackage(package) {
     }
 
     bool flattenPackage(BigBuffer* buffer) {
@@ -337,9 +243,6 @@
         pkgHeader->keyStrings = util::hostToDevice32(pkgWriter.size());
         StringPool::flattenUtf16(pkgWriter.getBuffer(), mKeyPool);
 
-        // Add the ResTable_package header/type/key strings to the offset.
-        mSymbols->shiftAllOffsets(pkgWriter.size());
-
         // Append the types.
         buffer->appendBuffer(std::move(typeBuffer));
 
@@ -349,12 +252,9 @@
 
 private:
     IDiagnostics* mDiag;
-    TableFlattenerOptions mOptions;
     ResourceTablePackage* mPackage;
     StringPool mTypePool;
     StringPool mKeyPool;
-    SymbolWriter* mSymbols;
-    StringPool* mSourcePool;
 
     template <typename T, bool IsItem>
     T* writeEntry(FlatEntry* entry, BigBuffer* buffer) {
@@ -376,62 +276,24 @@
             outEntry->flags |= ResTable_entry::FLAG_COMPLEX;
         }
 
-        outEntry->key.index = util::hostToDevice32(entry->entryKey);
-        outEntry->size = sizeof(T);
-
-        if (mOptions.useExtendedChunks) {
-            // Write the extra source block. This will be ignored by the Android runtime.
-            ResTable_entry_source* sourceBlock = buffer->nextBlock<ResTable_entry_source>();
-            sourceBlock->path.index = util::hostToDevice32(entry->sourcePathKey);
-            sourceBlock->line = util::hostToDevice32(entry->sourceLine);
-            sourceBlock->comment.index = util::hostToDevice32(entry->commentKey);
-            outEntry->size += sizeof(*sourceBlock);
-        }
-
         outEntry->flags = util::hostToDevice16(outEntry->flags);
-        outEntry->size = util::hostToDevice16(outEntry->size);
+        outEntry->key.index = util::hostToDevice32(entry->entryKey);
+        outEntry->size = util::hostToDevice16(sizeof(T));
         return result;
     }
 
     bool flattenValue(FlatEntry* entry, BigBuffer* buffer) {
         if (Item* item = valueCast<Item>(entry->value)) {
             writeEntry<ResTable_entry, true>(entry, buffer);
-            bool privateRef = false;
-            if (Reference* ref = valueCast<Reference>(entry->value)) {
-                // If there is no ID or the reference is private and we allow extended chunks,
-                // write out a 0 and mark the symbol table with the name of the reference.
-                privateRef = (ref->privateReference && mOptions.useExtendedChunks);
-                if (!ref->id || privateRef) {
-                    assert(ref->name && "reference must have at least a name");
-                    mSymbols->addSymbol(*ref, buffer->size() + offsetof(Res_value, data));
-                }
-            }
             Res_value* outValue = buffer->nextBlock<Res_value>();
             bool result = item->flatten(outValue);
             assert(result && "flatten failed");
-            if (privateRef) {
-                // Force the value of 0 so we look up the symbol at unflatten time.
-                outValue->data = 0;
-            }
             outValue->size = util::hostToDevice16(sizeof(*outValue));
         } else {
-            const size_t beforeEntry = buffer->size();
             ResTable_entry_ext* outEntry = writeEntry<ResTable_entry_ext, false>(entry, buffer);
-            MapFlattenVisitor visitor(mSymbols, entry, buffer, mSourcePool, mSourcePool,
-                                      mOptions.useExtendedChunks);
+            MapFlattenVisitor visitor(outEntry, buffer);
             entry->value->accept(&visitor);
-            outEntry->count = util::hostToDevice32(visitor.mEntryCount);
-            if (visitor.mParent) {
-                const bool forceSymbol = visitor.mParent->privateReference &&
-                        mOptions.useExtendedChunks;
-                if (!visitor.mParent->id || forceSymbol) {
-                    assert(visitor.mParent->name && "reference must have a name");
-                    mSymbols->addSymbol(*visitor.mParent,
-                                        beforeEntry + offsetof(ResTable_entry_ext, parent));
-                } else {
-                    outEntry->parent.ident = util::hostToDevice32(visitor.mParent->id.value().id);
-                }
-            }
+            visitor.finish();
         }
         return true;
     }
@@ -480,7 +342,7 @@
     std::vector<ResourceTableType*> collectAndSortTypes() {
         std::vector<ResourceTableType*> sortedTypes;
         for (auto& type : mPackage->types) {
-            if (type->type == ResourceType::kStyleable && !mOptions.useExtendedChunks) {
+            if (type->type == ResourceType::kStyleable) {
                 // Styleables aren't real Resource Types, they are represented in the R.java
                 // file.
                 continue;
@@ -540,10 +402,10 @@
 
             const size_t configCount = entry->values.size();
             for (size_t i = 0; i < configCount; i++) {
-                const ConfigDescription& config = entry->values[i].config;
+                const ConfigDescription& config = entry->values[i]->config;
                 for (size_t j = i + 1; j < configCount; j++) {
                     configMasks[entry->id.value()] |= util::hostToDevice32(
-                            config.diff(entry->values[j].config));
+                            config.diff(entry->values[j]->config));
                 }
             }
         }
@@ -551,52 +413,6 @@
         return true;
     }
 
-    bool flattenPublic(ResourceTableType* type, std::vector<ResourceEntry*>* sortedEntries,
-                       BigBuffer* buffer) {
-        ChunkWriter publicWriter(buffer);
-        Public_header* publicHeader = publicWriter.startChunk<Public_header>(RES_TABLE_PUBLIC_TYPE);
-        publicHeader->typeId = type->id.value();
-
-        for (ResourceEntry* entry : *sortedEntries) {
-            if (entry->symbolStatus.state != SymbolState::kUndefined) {
-                // Write the public status of this entry.
-                Public_entry* publicEntry = publicWriter.nextBlock<Public_entry>();
-                publicEntry->entryId = util::hostToDevice32(entry->id.value());
-                publicEntry->key.index = util::hostToDevice32(mKeyPool.makeRef(
-                        entry->name).getIndex());
-                publicEntry->source.path.index = util::hostToDevice32(mSourcePool->makeRef(
-                        util::utf8ToUtf16(entry->symbolStatus.source.path)).getIndex());
-                if (entry->symbolStatus.source.line) {
-                    publicEntry->source.line = util::hostToDevice32(
-                            entry->symbolStatus.source.line.value());
-                }
-                publicEntry->source.comment.index = util::hostToDevice32(mSourcePool->makeRef(
-                        entry->symbolStatus.comment).getIndex());
-
-                switch (entry->symbolStatus.state) {
-                case SymbolState::kPrivate:
-                    publicEntry->state = Public_entry::kPrivate;
-                    break;
-
-                case SymbolState::kPublic:
-                    publicEntry->state = Public_entry::kPublic;
-                    break;
-
-                case SymbolState::kUndefined:
-                    publicEntry->state = Public_entry::kUndefined;
-                    break;
-                }
-
-                // Don't hostToDevice until the last step.
-                publicHeader->count += 1;
-            }
-        }
-
-        publicHeader->count = util::hostToDevice32(publicHeader->count);
-        publicWriter.finish();
-        return true;
-    }
-
     bool flattenTypes(BigBuffer* buffer) {
         // Sort the types by their IDs. They will be inserted into the StringPool in this order.
         std::vector<ResourceTableType*> sortedTypes = collectAndSortTypes();
@@ -620,12 +436,6 @@
                 return false;
             }
 
-            if (mOptions.useExtendedChunks) {
-                if (!flattenPublic(type, &sortedEntries, buffer)) {
-                    return false;
-                }
-            }
-
             // The binary resource table lists resource entries for each configuration.
             // We store them inverted, where a resource entry lists the values for each
             // configuration available. Here we reverse this to match the binary table.
@@ -635,26 +445,8 @@
 
                 // Group values by configuration.
                 for (auto& configValue : entry->values) {
-                    Value* value = configValue.value.get();
-
-                    const StringPool::Ref sourceRef = mSourcePool->makeRef(
-                            util::utf8ToUtf16(value->getSource().path));
-
-                    uint32_t lineNumber = 0;
-                    if (value->getSource().line) {
-                        lineNumber = value->getSource().line.value();
-                    }
-
-                    const StringPool::Ref commentRef = mSourcePool->makeRef(value->getComment());
-
-                    configToEntryListMap[configValue.config]
-                            .push_back(FlatEntry{
-                                    entry,
-                                    value,
-                                    keyIndex,
-                                    (uint32_t) sourceRef.getIndex(),
-                                    lineNumber,
-                                    (uint32_t) commentRef.getIndex() });
+                    configToEntryListMap[configValue->config].push_back(FlatEntry{
+                            entry, configValue->value.get(), keyIndex });
                 }
             }
 
@@ -692,86 +484,18 @@
     // Flatten the values string pool.
     StringPool::flattenUtf8(tableWriter.getBuffer(), table->stringPool);
 
-    // If we have a reference to a symbol that doesn't exist, we don't know its resource ID.
-    // We encode the name of the symbol along with the offset of where to include the resource ID
-    // once it is found.
-    StringPool symbolPool;
-    std::vector<SymbolWriter::Entry> symbolOffsets;
-
-    // String pool holding the source paths of each value.
-    StringPool sourcePool;
-
     BigBuffer packageBuffer(1024);
 
     // Flatten each package.
     for (auto& package : table->packages) {
-        const size_t beforePackageSize = packageBuffer.size();
-
-        // All packages will share a single global symbol pool.
-        SymbolWriter packageSymbolWriter(&symbolPool);
-
-        PackageFlattener flattener(context->getDiagnostics(), mOptions, package.get(),
-                                   &packageSymbolWriter, &sourcePool);
+        PackageFlattener flattener(context->getDiagnostics(), package.get());
         if (!flattener.flattenPackage(&packageBuffer)) {
             return false;
         }
-
-        // The symbols are offset only from their own Package start. Offset them from the
-        // start of the packageBuffer.
-        packageSymbolWriter.shiftAllOffsets(beforePackageSize);
-
-        // Extract all the symbols to offset
-        symbolOffsets.insert(symbolOffsets.end(),
-                             std::make_move_iterator(packageSymbolWriter.symbols.begin()),
-                             std::make_move_iterator(packageSymbolWriter.symbols.end()));
     }
 
-    SymbolTable_entry* symbolEntryData = nullptr;
-    if (mOptions.useExtendedChunks) {
-        if (!symbolOffsets.empty()) {
-            // Sort the offsets so we can scan them linearly.
-            std::sort(symbolOffsets.begin(), symbolOffsets.end(),
-                      [](const SymbolWriter::Entry& a, const SymbolWriter::Entry& b) -> bool {
-                          return a.offset < b.offset;
-                      });
-
-            // Write the Symbol header.
-            ChunkWriter symbolWriter(tableWriter.getBuffer());
-            SymbolTable_header* symbolHeader = symbolWriter.startChunk<SymbolTable_header>(
-                    RES_TABLE_SYMBOL_TABLE_TYPE);
-            symbolHeader->count = util::hostToDevice32(symbolOffsets.size());
-
-            symbolEntryData = symbolWriter.nextBlock<SymbolTable_entry>(symbolOffsets.size());
-            StringPool::flattenUtf8(symbolWriter.getBuffer(), symbolPool);
-            symbolWriter.finish();
-        }
-
-        if (sourcePool.size() > 0) {
-            // Write out source pool.
-            ChunkWriter srcWriter(tableWriter.getBuffer());
-            srcWriter.startChunk<ResChunk_header>(RES_TABLE_SOURCE_POOL_TYPE);
-            StringPool::flattenUtf8(srcWriter.getBuffer(), sourcePool);
-            srcWriter.finish();
-        }
-    }
-
-    const size_t beforePackagesSize = tableWriter.size();
-
     // Finally merge all the packages into the main buffer.
     tableWriter.getBuffer()->appendBuffer(std::move(packageBuffer));
-
-    // Update the offsets to their final values.
-    if (symbolEntryData) {
-        for (SymbolWriter::Entry& entry : symbolOffsets) {
-            symbolEntryData->name.index = util::hostToDevice32(entry.name.getIndex());
-
-            // The symbols were all calculated with the packageBuffer offset. We need to
-            // add the beginning of the output buffer.
-            symbolEntryData->offset = util::hostToDevice32(entry.offset + beforePackagesSize);
-            symbolEntryData++;
-        }
-    }
-
     tableWriter.finish();
     return true;
 }
diff --git a/tools/aapt2/flatten/TableFlattener.h b/tools/aapt2/flatten/TableFlattener.h
index 901b129..0ab0197 100644
--- a/tools/aapt2/flatten/TableFlattener.h
+++ b/tools/aapt2/flatten/TableFlattener.h
@@ -24,28 +24,15 @@
 class BigBuffer;
 class ResourceTable;
 
-struct TableFlattenerOptions {
-    /**
-     * Specifies whether to output extended chunks, like
-     * source information and missing symbol entries. Default
-     * is false.
-     *
-     * Set this to true when emitting intermediate resource table.
-     */
-    bool useExtendedChunks = false;
-};
-
 class TableFlattener : public IResourceTableConsumer {
 public:
-    TableFlattener(BigBuffer* buffer, TableFlattenerOptions options) :
-            mBuffer(buffer), mOptions(options) {
+    TableFlattener(BigBuffer* buffer) : mBuffer(buffer) {
     }
 
     bool consume(IAaptContext* context, ResourceTable* table) override;
 
 private:
     BigBuffer* mBuffer;
-    TableFlattenerOptions mOptions;
 };
 
 } // namespace aapt
diff --git a/tools/aapt2/flatten/TableFlattener_test.cpp b/tools/aapt2/flatten/TableFlattener_test.cpp
index 7030603..39c4fd3 100644
--- a/tools/aapt2/flatten/TableFlattener_test.cpp
+++ b/tools/aapt2/flatten/TableFlattener_test.cpp
@@ -38,9 +38,7 @@
 
     ::testing::AssertionResult flatten(ResourceTable* table, ResTable* outTable) {
         BigBuffer buffer(1024);
-        TableFlattenerOptions options = {};
-        options.useExtendedChunks = true;
-        TableFlattener flattener(&buffer, options);
+        TableFlattener flattener(&buffer);
         if (!flattener.consume(mContext.get(), table)) {
             return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
         }
@@ -54,9 +52,7 @@
 
     ::testing::AssertionResult flatten(ResourceTable* table, ResourceTable* outTable) {
         BigBuffer buffer(1024);
-        TableFlattenerOptions options = {};
-        options.useExtendedChunks = true;
-        TableFlattener flattener(&buffer, options);
+        TableFlattener flattener(&buffer);
         if (!flattener.consume(mContext.get(), table)) {
             return ::testing::AssertionFailure() << "failed to flatten ResourceTable";
         }
@@ -210,58 +206,6 @@
                            Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
 }
 
-TEST_F(TableFlattenerTest, FlattenUnlinkedTable) {
-    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
-            .setPackageId(u"com.app.test", 0x7f)
-            .addValue(u"@com.app.test:integer/one", ResourceId(0x7f020000),
-                      test::buildReference(u"@android:integer/foo"))
-            .addValue(u"@com.app.test:style/Theme", ResourceId(0x7f030000), test::StyleBuilder()
-                    .setParent(u"@android:style/Theme.Material")
-                    .addItem(u"@android:attr/background", {})
-                    .addItem(u"@android:attr/colorAccent",
-                             test::buildReference(u"@com.app.test:color/green"))
-                    .build())
-            .build();
-
-    {
-        // Need access to stringPool to make RawString.
-        Style* style = test::getValue<Style>(table.get(), u"@com.app.test:style/Theme");
-        style->entries[0].value = util::make_unique<RawString>(table->stringPool.makeRef(u"foo"));
-    }
-
-    ResourceTable finalTable;
-    ASSERT_TRUE(flatten(table.get(), &finalTable));
-
-    Reference* ref = test::getValue<Reference>(&finalTable, u"@com.app.test:integer/one");
-    ASSERT_NE(ref, nullptr);
-    AAPT_ASSERT_TRUE(ref->name);
-    EXPECT_EQ(ref->name.value(), test::parseNameOrDie(u"@android:integer/foo"));
-
-    Style* style = test::getValue<Style>(&finalTable, u"@com.app.test:style/Theme");
-    ASSERT_NE(style, nullptr);
-    AAPT_ASSERT_TRUE(style->parent);
-    AAPT_ASSERT_TRUE(style->parent.value().name);
-    EXPECT_EQ(style->parent.value().name.value(),
-              test::parseNameOrDie(u"@android:style/Theme.Material"));
-
-    ASSERT_EQ(2u, style->entries.size());
-
-    AAPT_ASSERT_TRUE(style->entries[0].key.name);
-    EXPECT_EQ(style->entries[0].key.name.value(),
-              test::parseNameOrDie(u"@android:attr/background"));
-    RawString* raw = valueCast<RawString>(style->entries[0].value.get());
-    ASSERT_NE(raw, nullptr);
-    EXPECT_EQ(*raw->value, u"foo");
-
-    AAPT_ASSERT_TRUE(style->entries[1].key.name);
-    EXPECT_EQ(style->entries[1].key.name.value(),
-              test::parseNameOrDie(u"@android:attr/colorAccent"));
-    ref = valueCast<Reference>(style->entries[1].value.get());
-    ASSERT_NE(ref, nullptr);
-    AAPT_ASSERT_TRUE(ref->name);
-    EXPECT_EQ(ref->name.value(), test::parseNameOrDie(u"@com.app.test:color/green"));
-}
-
 TEST_F(TableFlattenerTest, FlattenMinMaxAttributes) {
     Attribute attr(false);
     attr.typeMask = android::ResTable_map::TYPE_INTEGER;
@@ -284,33 +228,4 @@
     EXPECT_EQ(attr.maxInt, actualAttr->maxInt);
 }
 
-TEST_F(TableFlattenerTest, FlattenSourceAndCommentsForChildrenOfCompoundValues) {
-    Style style;
-    Reference key(test::parseNameOrDie(u"@android:attr/foo"));
-    key.id = ResourceId(0x01010000);
-    key.setSource(Source("test").withLine(2));
-    key.setComment(StringPiece16(u"comment"));
-    style.entries.push_back(Style::Entry{ key, util::make_unique<Id>() });
-
-    test::ResourceTableBuilder builder = test::ResourceTableBuilder();
-    std::unique_ptr<ResourceTable> table = builder
-            .setPackageId(u"android", 0x01)
-            .addValue(u"@android:attr/foo", ResourceId(0x01010000),
-                      test::AttributeBuilder().build())
-            .addValue(u"@android:style/foo", ResourceId(0x01020000),
-                      std::unique_ptr<Style>(style.clone(builder.getStringPool())))
-            .build();
-
-    ResourceTable result;
-    ASSERT_TRUE(flatten(table.get(), &result));
-
-    Style* actualStyle = test::getValue<Style>(&result, u"@android:style/foo");
-    ASSERT_NE(nullptr, actualStyle);
-    ASSERT_EQ(1u, actualStyle->entries.size());
-
-    Reference* actualKey = &actualStyle->entries[0].key;
-    EXPECT_EQ(key.getSource(), actualKey->getSource());
-    EXPECT_EQ(key.getComment(), actualKey->getComment());
-}
-
 } // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index 7280f3a..6e340a2 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -23,7 +23,6 @@
 #include "java/AnnotationProcessor.h"
 #include "java/ClassDefinitionWriter.h"
 #include "java/JavaClassGenerator.h"
-#include "util/Comparators.h"
 #include "util/StringPiece.h"
 
 #include <algorithm>
@@ -258,12 +257,12 @@
         }
 
         for (const auto& configValue : entry->values) {
-            processor.appendComment(configValue.value->getComment());
+            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())) {
+            if (Attribute* attr = valueCast<Attribute>(entry->values.front()->value.get())) {
                 // We list out the available values for the given attribute.
                 addAttributeFormatDoc(&processor, attr);
             }
@@ -272,7 +271,7 @@
         if (type->type == ResourceType::kStyleable) {
             assert(!entry->values.empty());
             const Styleable* styleable = static_cast<const Styleable*>(
-                    entry->values.front().value.get());
+                    entry->values.front()->value.get());
             writeStyleableEntryForClass(outClassDef, &processor, packageNameToGenerate,
                                         unmangledName, styleable);
         } else {
@@ -311,11 +310,10 @@
 
             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) {
+                ResourceTableType* privType = package->findType(ResourceType::kAttrPrivate);
+                if (privType) {
                     result = writeEntriesForClass(&classDef, packageNameToGenerate,
-                                                  package.get(), iter->get());
+                                                  package.get(), privType);
                     if (!result) {
                         return false;
                     }
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index c7e603e..459c330 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -18,9 +18,7 @@
 #include "ResourceTable.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
-
 #include "link/Linkers.h"
-#include "util/Comparators.h"
 
 #include <algorithm>
 #include <cassert>
@@ -31,7 +29,12 @@
                                      const int sdkVersionToGenerate) {
     assert(sdkVersionToGenerate > config.sdkVersion);
     const auto endIter = entry->values.end();
-    auto iter = std::lower_bound(entry->values.begin(), endIter, config, cmp::lessThanConfig);
+    auto iter = entry->values.begin();
+    for (; iter != endIter; ++iter) {
+        if ((*iter)->config == config) {
+            break;
+        }
+    }
 
     // The source config came from this list, so it should be here.
     assert(iter != entry->values.end());
@@ -45,10 +48,10 @@
     // are no higher sdk level versions of this resource.
     ConfigDescription tempConfig(config);
     for (; iter != endIter; ++iter) {
-        tempConfig.sdkVersion = iter->config.sdkVersion;
-        if (tempConfig == iter->config) {
+        tempConfig.sdkVersion = (*iter)->config.sdkVersion;
+        if (tempConfig == (*iter)->config) {
             // The two configs are the same, check the sdk version.
-            return sdkVersionToGenerate < iter->config.sdkVersion;
+            return sdkVersionToGenerate < (*iter)->config.sdkVersion;
         }
     }
 
@@ -65,14 +68,14 @@
 
             for (auto& entry : type->entries) {
                 for (size_t i = 0; i < entry->values.size(); i++) {
-                    ResourceConfigValue& configValue = entry->values[i];
-                    if (configValue.config.sdkVersion >= SDK_LOLLIPOP_MR1) {
+                    ResourceConfigValue* configValue = entry->values[i].get();
+                    if (configValue->config.sdkVersion >= SDK_LOLLIPOP_MR1) {
                         // If this configuration is only used on L-MR1 then we don't need
                         // to do anything since we use private attributes since that version.
                         continue;
                     }
 
-                    if (Style* style = valueCast<Style>(configValue.value.get())) {
+                    if (Style* style = valueCast<Style>(configValue->value.get())) {
                         Maybe<size_t> minSdkStripped;
                         std::vector<Style::Entry> stripped;
 
@@ -82,7 +85,7 @@
 
                             // Find the SDK level that is higher than the configuration allows.
                             const size_t sdkLevel = findAttributeSdkLevel(iter->key.id.value());
-                            if (sdkLevel > std::max<size_t>(configValue.config.sdkVersion, 1)) {
+                            if (sdkLevel > std::max<size_t>(configValue->config.sdkVersion, 1)) {
                                 // Record that we are about to strip this.
                                 stripped.emplace_back(std::move(*iter));
 
@@ -105,10 +108,10 @@
                             // there is no other defined resource for the version we want to
                             // generate.
                             if (shouldGenerateVersionedResource(entry.get(),
-                                                                configValue.config,
+                                                                configValue->config,
                                                                 minSdkStripped.value())) {
                                 // Let's create a new Style for this versioned resource.
-                                ConfigDescription newConfig(configValue.config);
+                                ConfigDescription newConfig(configValue->config);
                                 newConfig.sdkVersion = minSdkStripped.value();
 
                                 std::unique_ptr<Style> newStyle(style->clone(&table->stringPool));
@@ -121,14 +124,8 @@
                                                          std::make_move_iterator(stripped.end()));
 
                                 // Insert the new Resource into the correct place.
-                                auto iter = std::lower_bound(entry->values.begin(),
-                                                             entry->values.end(),
-                                                             newConfig,
-                                                             cmp::lessThanConfig);
-
-                                entry->values.insert(
-                                        iter,
-                                        ResourceConfigValue{ newConfig, std::move(newStyle) });
+                                entry->findOrCreateValue(newConfig, {})->value =
+                                        std::move(newStyle);
                             }
                         }
                     }
diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp
index 29bcc93..9b3a87c 100644
--- a/tools/aapt2/link/AutoVersioner_test.cpp
+++ b/tools/aapt2/link/AutoVersioner_test.cpp
@@ -15,9 +15,7 @@
  */
 
 #include "ConfigDescription.h"
-
 #include "link/Linkers.h"
-
 #include "test/Builders.h"
 #include "test/Context.h"
 
@@ -31,9 +29,9 @@
     const ConfigDescription sw600dpLandConfig = test::parseConfigOrDie("sw600dp-land");
 
     ResourceEntry entry(u"foo");
-    entry.values.push_back(ResourceConfigValue{ defaultConfig });
-    entry.values.push_back(ResourceConfigValue{ landConfig });
-    entry.values.push_back(ResourceConfigValue{ sw600dpLandConfig });
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, ""));
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(landConfig, ""));
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(sw600dpLandConfig, ""));
 
     EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17));
     EXPECT_TRUE(shouldGenerateVersionedResource(&entry, landConfig, 17));
@@ -45,9 +43,9 @@
     const ConfigDescription v21Config = test::parseConfigOrDie("v21");
 
     ResourceEntry entry(u"foo");
-    entry.values.push_back(ResourceConfigValue{ defaultConfig });
-    entry.values.push_back(ResourceConfigValue{ sw600dpV13Config });
-    entry.values.push_back(ResourceConfigValue{ v21Config });
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(defaultConfig, ""));
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(sw600dpV13Config, ""));
+    entry.values.push_back(util::make_unique<ResourceConfigValue>(v21Config, ""));
 
     EXPECT_TRUE(shouldGenerateVersionedResource(&entry, defaultConfig, 17));
     EXPECT_FALSE(shouldGenerateVersionedResource(&entry, defaultConfig, 22));
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index fd76e88..3437ac0 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -19,6 +19,7 @@
 #include "Flags.h"
 #include "Locale.h"
 #include "NameMangler.h"
+#include "ResourceUtils.h"
 #include "compile/IdAssigner.h"
 #include "filter/ConfigFilter.h"
 #include "flatten/Archive.h"
@@ -30,17 +31,20 @@
 #include "java/ManifestClassGenerator.h"
 #include "java/ProguardRules.h"
 #include "link/Linkers.h"
+#include "link/ProductFilter.h"
 #include "link/ReferenceLinker.h"
 #include "link/ManifestFixer.h"
 #include "link/TableMerger.h"
 #include "process/IResourceTableConsumer.h"
 #include "process/SymbolTable.h"
+#include "proto/ProtoSerialize.h"
 #include "unflatten/BinaryResourceParser.h"
-#include "unflatten/FileExportHeaderReader.h"
 #include "util/Files.h"
 #include "util/StringPiece.h"
 #include "xml/XmlDom.h"
 
+#include <google/protobuf/io/coded_stream.h>
+
 #include <fstream>
 #include <sys/stat.h>
 #include <vector>
@@ -67,6 +71,7 @@
     Maybe<std::u16string> privateSymbols;
     ManifestFixerOptions manifestFixerOptions;
     IConfigFilter* configFilter = nullptr;
+    std::unordered_set<std::string> products;
 };
 
 struct LinkContext : public IAaptContext {
@@ -144,6 +149,22 @@
         return table;
     }
 
+    std::unique_ptr<ResourceTable> loadTableFromPb(const Source& source,
+                                                   const void* data, size_t len) {
+        pb::ResourceTable pbTable;
+        if (!pbTable.ParseFromArray(data, len)) {
+            mContext->getDiagnostics()->error(DiagMessage(source) << "invalid compiled table");
+            return {};
+        }
+
+        std::unique_ptr<ResourceTable> table = deserializeTableFromPb(pbTable, source,
+                                                                      mContext->getDiagnostics());
+        if (!table) {
+            return {};
+        }
+        return table;
+    }
+
     /**
      * Inflates an XML file from the source path.
      */
@@ -161,18 +182,16 @@
             const Source& source,
             const void* data, size_t len,
             IDiagnostics* diag) {
-        std::string errorStr;
-        ssize_t offset = getWrappedDataOffset(data, len, &errorStr);
-        if (offset < 0) {
-            diag->error(DiagMessage(source) << errorStr);
+        CompiledFileInputStream inputStream(data, len);
+        if (!inputStream.CompiledFile()) {
+            diag->error(DiagMessage(source) << "invalid compiled file header");
             return {};
         }
 
-        std::unique_ptr<xml::XmlResource> xmlRes = xml::inflate(
-                reinterpret_cast<const uint8_t*>(data) + static_cast<size_t>(offset),
-                len - static_cast<size_t>(offset),
-                diag,
-                source);
+        const uint8_t* xmlData = reinterpret_cast<const uint8_t*>(inputStream.data());
+        const size_t xmlDataLen = inputStream.size();
+
+        std::unique_ptr<xml::XmlResource> xmlRes = xml::inflate(xmlData, xmlDataLen, diag, source);
         if (!xmlRes) {
             return {};
         }
@@ -182,11 +201,16 @@
     static std::unique_ptr<ResourceFile> loadFileExportHeader(const Source& source,
                                                               const void* data, size_t len,
                                                               IDiagnostics* diag) {
-        std::unique_ptr<ResourceFile> resFile = util::make_unique<ResourceFile>();
-        std::string errorStr;
-        ssize_t offset = unwrapFileExportHeader(data, len, resFile.get(), &errorStr);
-        if (offset < 0) {
-            diag->error(DiagMessage(source) << errorStr);
+        CompiledFileInputStream inputStream(data, len);
+        const pb::CompiledFile* pbFile = inputStream.CompiledFile();
+        if (!pbFile) {
+            diag->error(DiagMessage(source) << "invalid compiled file header");
+            return {};
+        }
+
+        std::unique_ptr<ResourceFile> resFile = deserializeCompiledFileFromPb(*pbFile, source,
+                                                                              diag);
+        if (!resFile) {
             return {};
         }
         return resFile;
@@ -214,16 +238,16 @@
             return false;
         }
 
-        std::string errorStr;
-        ssize_t offset = getWrappedDataOffset(data->data(), data->size(), &errorStr);
-        if (offset < 0) {
-            mContext->getDiagnostics()->error(DiagMessage(file->getSource()) << errorStr);
+        CompiledFileInputStream inputStream(data->data(), data->size());
+        if (!inputStream.CompiledFile()) {
+            mContext->getDiagnostics()->error(DiagMessage(file->getSource())
+                                              << "invalid compiled file header");
             return false;
         }
 
         if (writer->startEntry(outPath, getCompressionFlags(outPath))) {
-            if (writer->writeEntry(reinterpret_cast<const uint8_t*>(data->data()) + offset,
-                                   data->size() - static_cast<size_t>(offset))) {
+            if (writer->writeEntry(reinterpret_cast<const uint8_t*>(inputStream.data()),
+                                   inputStream.size())) {
                 if (writer->finishEntry()) {
                     return true;
                 }
@@ -270,16 +294,16 @@
                         for (const auto& configValue : entry->values) {
                             // Special case the occurrence of an ID that is being generated for the
                             // 'android' package. This is due to legacy reasons.
-                            if (valueCast<Id>(configValue.value.get()) &&
+                            if (valueCast<Id>(configValue->value.get()) &&
                                     package->name == u"android") {
                                 mContext->getDiagnostics()->warn(
-                                        DiagMessage(configValue.value->getSource())
+                                        DiagMessage(configValue->value->getSource())
                                         << "generated id '" << resName
                                         << "' for external package '" << package->name
                                         << "'");
                             } else {
                                 mContext->getDiagnostics()->error(
-                                        DiagMessage(configValue.value->getSource())
+                                        DiagMessage(configValue->value->getSource())
                                         << "defined resource '" << resName
                                         << "' for external package '" << package->name
                                         << "'");
@@ -307,9 +331,7 @@
 
     bool flattenTable(ResourceTable* table, IArchiveWriter* writer) {
         BigBuffer buffer(1024);
-        TableFlattenerOptions options = {};
-        options.useExtendedChunks = mOptions.staticLib;
-        TableFlattener flattener(&buffer, options);
+        TableFlattener flattener(&buffer);
         if (!flattener.consume(mContext, table)) {
             return false;
         }
@@ -445,8 +467,8 @@
             return false;
         }
 
-        std::unique_ptr<ResourceTable> table = loadTable(file->getSource(), data->data(),
-                                                         data->size());
+        std::unique_ptr<ResourceTable> table = loadTableFromPb(file->getSource(), data->data(),
+                                                               data->size());
         if (!table) {
             return false;
         }
@@ -492,7 +514,10 @@
 
             std::unique_ptr<Id> id = util::make_unique<Id>();
             id->setSource(fileDesc->source.withLine(exportedSymbol.line));
-            bool result = mFinalTable.addResourceAllowMangled(resName, {}, std::move(id),
+            bool result = mFinalTable.addResourceAllowMangled(resName,
+                                                              ConfigDescription::defaultConfig(),
+                                                              std::string(),
+                                                              std::move(id),
                                                               mContext->getDiagnostics());
             if (!result) {
                 return false;
@@ -661,6 +686,12 @@
                 mContext->getDiagnostics()->error(DiagMessage() << "failed linking references");
                 return 1;
             }
+
+            ProductFilter productFilter(mOptions.products);
+            if (!productFilter.consume(mContext, &mFinalTable)) {
+                mContext->getDiagnostics()->error(DiagMessage() << "failed stripping products");
+                return 1;
+            }
         }
 
         proguard::KeepSet proguardKeepSet;
@@ -911,6 +942,7 @@
     Maybe<std::string> customJavaPackage;
     std::vector<std::string> extraJavaPackages;
     Maybe<std::string> configs;
+    Maybe<std::string> productList;
     bool legacyXFlag = false;
     bool requireLocalization = false;
     Flags flags = Flags()
@@ -934,6 +966,8 @@
                             &requireLocalization)
             .optionalFlag("-c", "Comma separated list of configurations to include. The default\n"
                                 "is all configurations", &configs)
+            .optionalFlag("--product", "Comma separated list of product names to keep",
+                          &productList)
             .optionalSwitch("--output-to-dir", "Outputs the APK contents to a directory specified "
                             "by -o",
                             &options.outputToDirectory)
@@ -1019,6 +1053,14 @@
         }
     }
 
+    if (productList) {
+        for (StringPiece product : util::tokenize<char>(productList.value(), ',')) {
+            if (product != "" && product != "default") {
+                options.products.insert(product.toString());
+            }
+        }
+    }
+
     AxisConfigFilter filter;
     if (configs) {
         for (const StringPiece& configStr : util::tokenize<char>(configs.value(), ',')) {
diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h
index 4d3a483..ec532ab 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -26,7 +26,7 @@
 namespace aapt {
 
 class ResourceTable;
-struct ResourceEntry;
+class ResourceEntry;
 struct ConfigDescription;
 
 /**
diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp
new file mode 100644
index 0000000..8784e89
--- /dev/null
+++ b/tools/aapt2/link/ProductFilter.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "link/ProductFilter.h"
+
+namespace aapt {
+
+ProductFilter::ResourceConfigValueIter
+ProductFilter::selectProductToKeep(const ResourceNameRef& name,
+                                   const ResourceConfigValueIter begin,
+                                   const ResourceConfigValueIter end,
+                                   IDiagnostics* diag) {
+    ResourceConfigValueIter defaultProductIter = end;
+    ResourceConfigValueIter selectedProductIter = end;
+
+    for (ResourceConfigValueIter iter = begin; iter != end; ++iter) {
+        ResourceConfigValue* configValue = iter->get();
+        if (mProducts.find(configValue->product) != mProducts.end()) {
+            if (selectedProductIter != end) {
+                // We have two possible values for this product!
+                diag->error(DiagMessage(configValue->value->getSource())
+                            << "selection of product '" << configValue->product
+                            << "' for resource " << name << " is ambiguous");
+
+                ResourceConfigValue* previouslySelectedConfigValue = selectedProductIter->get();
+                diag->note(DiagMessage(previouslySelectedConfigValue->value->getSource())
+                           << "product '" << previouslySelectedConfigValue->product
+                           << "' is also a candidate");
+                return end;
+            }
+
+            // Select this product.
+            selectedProductIter = iter;
+        }
+
+        if (configValue->product.empty() || configValue->product == "default") {
+            if (defaultProductIter != end) {
+                // We have two possible default values.
+                diag->error(DiagMessage(configValue->value->getSource())
+                            << "multiple default products defined for resource " << name);
+
+                ResourceConfigValue* previouslyDefaultConfigValue = defaultProductIter->get();
+                diag->note(DiagMessage(previouslyDefaultConfigValue->value->getSource())
+                           << "default product also defined here");
+                return end;
+            }
+
+            // Mark the default.
+            defaultProductIter = iter;
+        }
+    }
+
+    if (defaultProductIter == end) {
+        diag->error(DiagMessage() << "no default product defined for resource " << name);
+        return end;
+    }
+
+    if (selectedProductIter == end) {
+        selectedProductIter = defaultProductIter;
+    }
+    return selectedProductIter;
+}
+
+bool ProductFilter::consume(IAaptContext* context, ResourceTable* table) {
+    bool error = false;
+    for (auto& pkg : table->packages) {
+        for (auto& type : pkg->types) {
+            for (auto& entry : type->entries) {
+                std::vector<std::unique_ptr<ResourceConfigValue>> newValues;
+
+                ResourceConfigValueIter iter = entry->values.begin();
+                ResourceConfigValueIter startRangeIter = iter;
+                while (iter != entry->values.end()) {
+                    ++iter;
+                    if (iter == entry->values.end() ||
+                            (*iter)->config != (*startRangeIter)->config) {
+
+                        // End of the array, or we saw a different config,
+                        // so this must be the end of a range of products.
+                        // Select the product to keep from the set of products defined.
+                        ResourceNameRef name(pkg->name, type->type, entry->name);
+                        auto valueToKeep = selectProductToKeep(name, startRangeIter, iter,
+                                                               context->getDiagnostics());
+                        if (valueToKeep == iter) {
+                            // An error occurred, we could not pick a product.
+                            error = true;
+                        } else {
+                            // We selected a product to keep. Move it to the new array.
+                            newValues.push_back(std::move(*valueToKeep));
+                        }
+
+                        // Start the next range of products.
+                        startRangeIter = iter;
+                    }
+                }
+
+                // Now move the new values in to place.
+                entry->values = std::move(newValues);
+            }
+        }
+    }
+    return !error;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/link/ProductFilter.h b/tools/aapt2/link/ProductFilter.h
new file mode 100644
index 0000000..d2edd38
--- /dev/null
+++ b/tools/aapt2/link/ProductFilter.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_LINK_PRODUCTFILTER_H
+#define AAPT_LINK_PRODUCTFILTER_H
+
+#include "ResourceTable.h"
+#include "process/IResourceTableConsumer.h"
+
+#include <android-base/macros.h>
+#include <unordered_set>
+
+namespace aapt {
+
+class ProductFilter {
+public:
+    using ResourceConfigValueIter = std::vector<std::unique_ptr<ResourceConfigValue>>::iterator;
+
+    ProductFilter(std::unordered_set<std::string> products) : mProducts(products) { }
+
+    ResourceConfigValueIter selectProductToKeep(const ResourceNameRef& name,
+                                                const ResourceConfigValueIter begin,
+                                                const ResourceConfigValueIter end,
+                                                IDiagnostics* diag);
+
+    bool consume(IAaptContext* context, ResourceTable* table);
+
+private:
+    std::unordered_set<std::string> mProducts;
+
+    DISALLOW_COPY_AND_ASSIGN(ProductFilter);
+};
+
+} // namespace aapt
+
+#endif /* AAPT_LINK_PRODUCTFILTER_H */
diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp
new file mode 100644
index 0000000..f4f756a
--- /dev/null
+++ b/tools/aapt2/link/ProductFilter_test.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "link/ProductFilter.h"
+#include "test/Builders.h"
+#include "test/Context.h"
+
+#include <gtest/gtest.h>
+
+namespace aapt {
+
+TEST(ProductFilterTest, SelectTwoProducts) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+
+    const ConfigDescription land = test::parseConfigOrDie("land");
+    const ConfigDescription port = test::parseConfigOrDie("port");
+
+    ResourceTable table;
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  land, "",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("land/default.xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  land, "tablet",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("land/tablet.xml")).build(),
+                                  context->getDiagnostics()));
+
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  port, "",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("port/default.xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  port, "tablet",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("port/tablet.xml")).build(),
+                                  context->getDiagnostics()));
+
+    ProductFilter filter({ "tablet" });
+    ASSERT_TRUE(filter.consume(context.get(), &table));
+
+    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             land, ""));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             land, "tablet"));
+    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             port, ""));
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             port, "tablet"));
+}
+
+TEST(ProductFilterTest, SelectDefaultProduct) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+
+    ResourceTable table;
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("default.xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "tablet",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("tablet.xml")).build(),
+                                  context->getDiagnostics()));
+
+    ProductFilter filter({});
+    ASSERT_TRUE(filter.consume(context.get(), &table));
+
+    EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             ConfigDescription::defaultConfig(),
+                                                             ""));
+    EXPECT_EQ(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/one",
+                                                             ConfigDescription::defaultConfig(),
+                                                             "tablet"));
+}
+
+TEST(ProductFilterTest, FailOnAmbiguousProduct) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+
+    ResourceTable table;
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("default.xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "tablet",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("tablet.xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "no-sdcard",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("no-sdcard.xml")).build(),
+                                  context->getDiagnostics()));
+
+    ProductFilter filter({ "tablet", "no-sdcard" });
+    ASSERT_FALSE(filter.consume(context.get(), &table));
+}
+
+TEST(ProductFilterTest, FailOnMultipleDefaults) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+
+    ResourceTable table;
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source(".xml")).build(),
+                                  context->getDiagnostics()));
+    ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/one"),
+                                  ConfigDescription::defaultConfig(), "default",
+                                  test::ValueBuilder<Id>()
+                                          .setSource(Source("default.xml")).build(),
+                                  context->getDiagnostics()));
+
+    ProductFilter filter({});
+    ASSERT_FALSE(filter.consume(context.get(), &table));
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 2743539..ef3fe4f 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -316,7 +316,7 @@
                                                &table->stringPool, &declStack, &callSite);
 
                 for (auto& configValue : entry->values) {
-                    configValue.value->accept(&visitor);
+                    configValue->value->accept(&visitor);
                 }
 
                 if (visitor.hasError()) {
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index e01a004..2ecd5b0 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -18,9 +18,7 @@
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
-
 #include "link/TableMerger.h"
-#include "util/Comparators.h"
 #include "util/Util.h"
 
 #include <cassert>
@@ -197,28 +195,28 @@
 
             ResourceNameRef resName(mMasterPackage->name, dstType->type, dstEntry->name);
 
-            for (ResourceConfigValue& srcValue : srcEntry->values) {
-                auto iter = std::lower_bound(dstEntry->values.begin(), dstEntry->values.end(),
-                                             srcValue.config, cmp::lessThanConfig);
+            for (auto& srcValue : srcEntry->values) {
+                ResourceConfigValue* dstValue = dstEntry->findValue(srcValue->config,
+                                                                    srcValue->product);
 
                 const bool stripConfig = mOptions.filter ?
-                        !mOptions.filter->match(srcValue.config) : false;
+                        !mOptions.filter->match(srcValue->config) : false;
 
-                if (iter != dstEntry->values.end() && iter->config == srcValue.config) {
+                if (dstValue) {
                     const int collisionResult = ResourceTable::resolveValueCollision(
-                            iter->value.get(), srcValue.value.get());
+                            dstValue->value.get(), srcValue->value.get());
                     if (collisionResult == 0 && !overlay) {
                         // Error!
                         ResourceNameRef resourceName(srcPackage->name,
                                                      srcType->type,
                                                      srcEntry->name);
 
-                        mContext->getDiagnostics()->error(DiagMessage(srcValue.value->getSource())
+                        mContext->getDiagnostics()->error(DiagMessage(srcValue->value->getSource())
                                                           << "resource '" << resourceName
                                                           << "' has a conflicting value for "
                                                           << "configuration ("
-                                                          << srcValue.config << ")");
-                        mContext->getDiagnostics()->note(DiagMessage(iter->value->getSource())
+                                                          << srcValue->config << ")");
+                        mContext->getDiagnostics()->note(DiagMessage(dstValue->value->getSource())
                                                          << "originally defined here");
                         error = true;
                         continue;
@@ -227,16 +225,18 @@
                         continue;
                     }
 
-                } else if (!stripConfig){
-                    // Insert a place holder value. We will fill it in below.
-                    iter = dstEntry->values.insert(iter, ResourceConfigValue{ srcValue.config });
                 }
 
                 if (stripConfig) {
                     continue;
                 }
 
-                if (FileReference* f = valueCast<FileReference>(srcValue.value.get())) {
+                if (!dstValue) {
+                    // Force create the entry if we didn't have it.
+                    dstValue = dstEntry->findOrCreateValue(srcValue->config, srcValue->product);
+                }
+
+                if (FileReference* f = valueCast<FileReference>(srcValue->value.get())) {
                     std::unique_ptr<FileReference> newFileRef;
                     if (manglePackage) {
                         newFileRef = cloneAndMangleFile(srcPackage->name, *f);
@@ -246,15 +246,15 @@
                     }
 
                     if (callback) {
-                        if (!callback(resName, iter->config, newFileRef.get(), f)) {
+                        if (!callback(resName, srcValue->config, newFileRef.get(), f)) {
                             error = true;
                             continue;
                         }
                     }
-                    iter->value = std::move(newFileRef);
+                    dstValue->value = std::move(newFileRef);
 
                 } else {
-                    iter->value = std::unique_ptr<Value>(srcValue.value->clone(
+                    dstValue->value = std::unique_ptr<Value>(srcValue->value->clone(
                             &mMasterTable->stringPool));
                 }
             }
@@ -290,7 +290,8 @@
     ResourceTablePackage* pkg = table.createPackage(fileDesc.name.package, 0x0);
     pkg->findOrCreateType(fileDesc.name.type)
             ->findOrCreateEntry(fileDesc.name.entry)
-            ->values.push_back(ResourceConfigValue{ fileDesc.config, std::move(fileRef) });
+            ->findOrCreateValue(fileDesc.config, {})
+            ->value = std::move(fileRef);
 
     auto callback = [&](const ResourceNameRef& name, const ConfigDescription& config,
                        FileReference* newFile, FileReference* oldFile) -> bool {
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 6ad2f9c..b6030a2 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -17,9 +17,7 @@
 #include "ConfigDescription.h"
 #include "Resource.h"
 #include "ValueVisitor.h"
-
 #include "process/SymbolTable.h"
-#include "util/Comparators.h"
 #include "util/Util.h"
 
 #include <androidfw/AssetManager.h>
@@ -55,12 +53,10 @@
 
     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::lessThanConfig);
-
-        if (iter != sr.entry->values.end() && iter->config == kDefaultConfig) {
+        ResourceConfigValue* configValue = sr.entry->findValue(kDefaultConfig);
+        if (configValue) {
             // This resource has an Attribute.
-            if (Attribute* attr = valueCast<Attribute>(iter->value.get())) {
+            if (Attribute* attr = valueCast<Attribute>(configValue->value.get())) {
                 symbol->attribute = util::make_unique<Attribute>(*attr);
             } else {
                 return {};
diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp
new file mode 100644
index 0000000..99981c5
--- /dev/null
+++ b/tools/aapt2/proto/ProtoHelpers.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "proto/ProtoHelpers.h"
+
+namespace aapt {
+
+void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool) {
+    BigBuffer buffer(1024);
+    StringPool::flattenUtf8(&buffer, pool);
+
+    std::string* data = outPbPool->mutable_data();
+    data->reserve(buffer.size());
+
+    size_t offset = 0;
+    for (const BigBuffer::Block& block : buffer) {
+        data->insert(data->begin() + offset, block.buffer.get(), block.buffer.get() + block.size);
+        offset += block.size;
+    }
+}
+
+void serializeSourceToPb(const Source& source, StringPool* srcPool, pb::Source* outPbSource) {
+    StringPool::Ref ref = srcPool->makeRef(util::utf8ToUtf16(source.path));
+    outPbSource->set_path_idx(static_cast<uint32_t>(ref.getIndex()));
+    if (source.line) {
+        outPbSource->set_line_no(static_cast<uint32_t>(source.line.value()));
+    }
+}
+
+void deserializeSourceFromPb(const pb::Source& pbSource, const android::ResStringPool& srcPool,
+                             Source* outSource) {
+    if (pbSource.has_path_idx()) {
+        outSource->path = util::getString8(srcPool, pbSource.path_idx()).toString();
+    }
+
+    if (pbSource.has_line_no()) {
+        outSource->line = static_cast<size_t>(pbSource.line_no());
+    }
+}
+
+pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state) {
+    switch (state) {
+    case SymbolState::kPrivate: return pb::SymbolStatus_Visibility_Private;
+    case SymbolState::kPublic: return pb::SymbolStatus_Visibility_Public;
+    default: break;
+    }
+    return pb::SymbolStatus_Visibility_Unknown;
+}
+
+SymbolState deserializeVisibilityFromPb(pb::SymbolStatus_Visibility pbVisibility) {
+    switch (pbVisibility) {
+    case pb::SymbolStatus_Visibility_Private: return SymbolState::kPrivate;
+    case pb::SymbolStatus_Visibility_Public: return SymbolState::kPublic;
+    default: break;
+    }
+    return SymbolState::kUndefined;
+}
+
+void serializeConfig(const ConfigDescription& config, pb::ConfigDescription* outPbConfig) {
+    android::ResTable_config flatConfig = config;
+    flatConfig.size = sizeof(flatConfig);
+    flatConfig.swapHtoD();
+    outPbConfig->set_data(&flatConfig, sizeof(flatConfig));
+}
+
+bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig,
+                                        ConfigDescription* outConfig) {
+    if (!pbConfig.has_data()) {
+        return false;
+    }
+
+    const android::ResTable_config* config;
+    if (pbConfig.data().size() > sizeof(*config)) {
+        return false;
+    }
+
+    config = reinterpret_cast<const android::ResTable_config*>(pbConfig.data().data());
+    outConfig->copyFromDtoH(*config);
+    return true;
+}
+
+pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type) {
+    switch (type) {
+    case Reference::Type::kResource:  return pb::Reference_Type_Ref;
+    case Reference::Type::kAttribute: return pb::Reference_Type_Attr;
+    default: break;
+    }
+    return pb::Reference_Type_Ref;
+}
+
+Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType) {
+    switch (pbType) {
+    case pb::Reference_Type_Ref:  return Reference::Type::kResource;
+    case pb::Reference_Type_Attr: return Reference::Type::kAttribute;
+    default: break;
+    }
+    return Reference::Type::kResource;
+}
+
+pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx) {
+    switch (pluralIdx) {
+    case Plural::Zero:  return pb::Plural_Arity_Zero;
+    case Plural::One:   return pb::Plural_Arity_One;
+    case Plural::Two:   return pb::Plural_Arity_Two;
+    case Plural::Few:   return pb::Plural_Arity_Few;
+    case Plural::Many:  return pb::Plural_Arity_Many;
+    default: break;
+    }
+    return pb::Plural_Arity_Other;
+}
+
+size_t deserializePluralEnumFromPb(pb::Plural_Arity arity) {
+    switch (arity) {
+    case pb::Plural_Arity_Zero: return Plural::Zero;
+    case pb::Plural_Arity_One:  return Plural::One;
+    case pb::Plural_Arity_Two:  return Plural::Two;
+    case pb::Plural_Arity_Few:  return Plural::Few;
+    case pb::Plural_Arity_Many: return Plural::Many;
+    default: break;
+    }
+    return Plural::Other;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/proto/ProtoHelpers.h b/tools/aapt2/proto/ProtoHelpers.h
new file mode 100644
index 0000000..02e67f1
--- /dev/null
+++ b/tools/aapt2/proto/ProtoHelpers.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_PROTO_PROTOHELPERS_H
+#define AAPT_PROTO_PROTOHELPERS_H
+
+#include "ConfigDescription.h"
+#include "ResourceTable.h"
+#include "Source.h"
+#include "StringPool.h"
+
+#include "proto/frameworks/base/tools/aapt2/Format.pb.h"
+
+#include <androidfw/ResourceTypes.h>
+
+namespace aapt {
+
+void serializeStringPoolToPb(const StringPool& pool, pb::StringPool* outPbPool);
+
+void serializeSourceToPb(const Source& source, StringPool* srcPool, pb::Source* outPbSource);
+void deserializeSourceFromPb(const pb::Source& pbSource, const android::ResStringPool& srcPool,
+                             Source* outSource);
+
+pb::SymbolStatus_Visibility serializeVisibilityToPb(SymbolState state);
+SymbolState deserializeVisibilityFromPb(pb::SymbolStatus_Visibility pbVisibility);
+
+void serializeConfig(const ConfigDescription& config, pb::ConfigDescription* outPbConfig);
+bool deserializeConfigDescriptionFromPb(const pb::ConfigDescription& pbConfig,
+                                        ConfigDescription* outConfig);
+
+pb::Reference_Type serializeReferenceTypeToPb(Reference::Type type);
+Reference::Type deserializeReferenceTypeFromPb(pb::Reference_Type pbType);
+
+pb::Plural_Arity serializePluralEnumToPb(size_t pluralIdx);
+size_t deserializePluralEnumFromPb(pb::Plural_Arity arity);
+
+} // namespace aapt
+
+#endif /* AAPT_PROTO_PROTOHELPERS_H */
diff --git a/tools/aapt2/proto/ProtoSerialize.h b/tools/aapt2/proto/ProtoSerialize.h
new file mode 100644
index 0000000..6e224ab
--- /dev/null
+++ b/tools/aapt2/proto/ProtoSerialize.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AAPT_FLATTEN_TABLEPROTOSERIALIZER_H
+#define AAPT_FLATTEN_TABLEPROTOSERIALIZER_H
+
+#include "Diagnostics.h"
+#include "ResourceTable.h"
+#include "Source.h"
+#include "proto/ProtoHelpers.h"
+
+#include <android-base/macros.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+
+namespace aapt {
+
+std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table);
+std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
+                                                      const Source& source,
+                                                      IDiagnostics* diag);
+
+std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb(const ResourceFile& file);
+std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFile& pbFile,
+                                                            const Source& source,
+                                                            IDiagnostics* diag);
+
+class CompiledFileOutputStream : public google::protobuf::io::CopyingOutputStream {
+public:
+    CompiledFileOutputStream(google::protobuf::io::ZeroCopyOutputStream* out,
+                             pb::CompiledFile* pbFile);
+    bool Write(const void* data, int size) override;
+    bool Finish();
+
+private:
+    bool ensureFileWritten();
+
+    google::protobuf::io::CodedOutputStream mOut;
+    pb::CompiledFile* mPbFile;
+
+    DISALLOW_COPY_AND_ASSIGN(CompiledFileOutputStream);
+};
+
+class CompiledFileInputStream {
+public:
+    CompiledFileInputStream(const void* data, size_t size);
+
+    const pb::CompiledFile* CompiledFile();
+
+    const void* data();
+    size_t size();
+
+private:
+    google::protobuf::io::CodedInputStream mIn;
+    std::unique_ptr<pb::CompiledFile> mPbFile;
+    const uint8_t* mData;
+    size_t mSize;
+
+    DISALLOW_COPY_AND_ASSIGN(CompiledFileInputStream);
+};
+
+} // namespace aapt
+
+#endif /* AAPT_FLATTEN_TABLEPROTOSERIALIZER_H */
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
new file mode 100644
index 0000000..9856a00
--- /dev/null
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ResourceTable.h"
+#include "ResourceUtils.h"
+#include "ValueVisitor.h"
+#include "proto/ProtoHelpers.h"
+#include "proto/ProtoSerialize.h"
+
+#include <androidfw/ResourceTypes.h>
+
+namespace aapt {
+
+namespace {
+
+class ReferenceIdToNameVisitor : public ValueVisitor {
+public:
+    using ValueVisitor::visit;
+
+    ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping) :
+            mMapping(mapping) {
+        assert(mMapping);
+    }
+
+    void visit(Reference* reference) override {
+        if (!reference->id || !reference->id.value().isValid()) {
+            return;
+        }
+
+        ResourceId id = reference->id.value();
+        auto cacheIter = mMapping->find(id);
+        if (cacheIter != mMapping->end()) {
+            reference->name = cacheIter->second.toResourceName();
+        }
+    }
+
+private:
+    const std::map<ResourceId, ResourceNameRef>* mMapping;
+};
+
+class PackagePbDeserializer {
+public:
+    PackagePbDeserializer(const android::ResStringPool* valuePool,
+                          const android::ResStringPool* sourcePool,
+                          const android::ResStringPool* symbolPool,
+                          const Source& source, IDiagnostics* diag) :
+            mValuePool(valuePool), mSourcePool(sourcePool), mSymbolPool(symbolPool),
+            mSource(source), mDiag(diag) {
+    }
+
+public:
+    bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
+        Maybe<uint8_t> id;
+        if (pbPackage.has_package_id()) {
+            id = static_cast<uint8_t>(pbPackage.package_id());
+        }
+
+        std::map<ResourceId, ResourceNameRef> idIndex;
+
+        ResourceTablePackage* pkg = table->createPackage(
+                util::utf8ToUtf16(pbPackage.package_name()), id);
+        for (const pb::Type& pbType : pbPackage.types()) {
+            const ResourceType* resType = parseResourceType(util::utf8ToUtf16(pbType.name()));
+            if (!resType) {
+                mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name() << "'");
+                return {};
+            }
+
+            ResourceTableType* type = pkg->findOrCreateType(*resType);
+
+            for (const pb::Entry& pbEntry : pbType.entries()) {
+                ResourceEntry* entry = type->findOrCreateEntry(util::utf8ToUtf16(pbEntry.name()));
+
+                // Deserialize the symbol status (public/private with source and comments).
+                if (pbEntry.has_symbol_status()) {
+                    const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
+                    if (pbStatus.has_source()) {
+                        deserializeSourceFromPb(pbStatus.source(), *mSourcePool,
+                                                &entry->symbolStatus.source);
+                    }
+
+                    if (pbStatus.has_comment()) {
+                        entry->symbolStatus.comment = util::utf8ToUtf16(pbStatus.comment());
+                    }
+
+                    SymbolState visibility = deserializeVisibilityFromPb(pbStatus.visibility());
+                    entry->symbolStatus.state = visibility;
+
+                    if (visibility == SymbolState::kPublic) {
+                        // This is a public symbol, we must encode the ID now if there is one.
+                        if (pbEntry.has_id()) {
+                            entry->id = static_cast<uint16_t>(pbEntry.id());
+                        }
+
+                        if (type->symbolStatus.state != SymbolState::kPublic) {
+                            // If the type has not been made public, do so now.
+                            type->symbolStatus.state = SymbolState::kPublic;
+                            if (pbType.has_id()) {
+                                type->id = static_cast<uint8_t>(pbType.id());
+                            }
+                        }
+                    } else if (visibility == SymbolState::kPrivate) {
+                        if (type->symbolStatus.state == SymbolState::kUndefined) {
+                            type->symbolStatus.state = SymbolState::kPrivate;
+                        }
+                    }
+                }
+
+                ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
+                if (resId.isValid()) {
+                    idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
+                }
+
+                for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) {
+                    const pb::ConfigDescription& pbConfig = pbConfigValue.config();
+
+                    ConfigDescription config;
+                    if (!deserializeConfigDescriptionFromPb(pbConfig, &config)) {
+                        mDiag->error(DiagMessage(mSource) << "invalid configuration");
+                        return {};
+                    }
+
+                    ResourceConfigValue* configValue = entry->findOrCreateValue(config,
+                                                                                pbConfig.product());
+                    if (configValue->value) {
+                        // Duplicate config.
+                        mDiag->error(DiagMessage(mSource) << "duplicate configuration");
+                        return {};
+                    }
+
+                    configValue->value = deserializeValueFromPb(pbConfigValue.value(),
+                                                                config, &table->stringPool);
+                    if (!configValue->value) {
+                        return {};
+                    }
+                }
+            }
+        }
+
+        ReferenceIdToNameVisitor visitor(&idIndex);
+        visitAllValuesInPackage(pkg, &visitor);
+        return true;
+    }
+
+private:
+    std::unique_ptr<Item> deserializeItemFromPb(const pb::Item& pbItem,
+                                                const ConfigDescription& config,
+                                                StringPool* pool) {
+        if (pbItem.has_ref()) {
+            const pb::Reference& pbRef = pbItem.ref();
+            std::unique_ptr<Reference> ref = util::make_unique<Reference>();
+            if (!deserializeReferenceFromPb(pbRef, ref.get())) {
+                return {};
+            }
+            return std::move(ref);
+
+        } else if (pbItem.has_prim()) {
+            const pb::Primitive& pbPrim = pbItem.prim();
+            android::Res_value prim = {};
+            prim.dataType = static_cast<uint8_t>(pbPrim.type());
+            prim.data = pbPrim.data();
+            return util::make_unique<BinaryPrimitive>(prim);
+
+        } else if (pbItem.has_id()) {
+            return util::make_unique<Id>();
+
+        } else if (pbItem.has_str()) {
+            const uint32_t idx = pbItem.str().idx();
+            StringPiece16 str = util::getString(*mValuePool, idx);
+
+            const android::ResStringPool_span* spans = mValuePool->styleAt(idx);
+            if (spans && spans->name.index != android::ResStringPool_span::END) {
+                StyleString styleStr = { str.toString() };
+                while (spans->name.index != android::ResStringPool_span::END) {
+                    styleStr.spans.push_back(Span{
+                            util::getString(*mValuePool, spans->name.index).toString(),
+                            spans->firstChar,
+                            spans->lastChar
+                    });
+                    spans++;
+                }
+                return util::make_unique<StyledString>(
+                        pool->makeRef(styleStr, StringPool::Context{ 1, config }));
+            }
+            return util::make_unique<String>(
+                    pool->makeRef(str, StringPool::Context{ 1, config }));
+
+        } else if (pbItem.has_raw_str()) {
+            const uint32_t idx = pbItem.raw_str().idx();
+            StringPiece16 str = util::getString(*mValuePool, idx);
+            return util::make_unique<RawString>(
+                    pool->makeRef(str, StringPool::Context{ 1, config }));
+
+        } else if (pbItem.has_file()) {
+            const uint32_t idx = pbItem.file().path_idx();
+            StringPiece16 str = util::getString(*mValuePool, idx);
+            return util::make_unique<FileReference>(
+                    pool->makeRef(str, StringPool::Context{ 0, config }));
+
+        } else {
+            mDiag->error(DiagMessage(mSource) << "unknown item");
+        }
+        return {};
+    }
+
+    std::unique_ptr<Value> deserializeValueFromPb(const pb::Value& pbValue,
+                                                  const ConfigDescription& config,
+                                                  StringPool* pool) {
+        const bool isWeak = pbValue.has_weak() ? pbValue.weak() : false;
+
+        std::unique_ptr<Value> value;
+        if (pbValue.has_item()) {
+            value = deserializeItemFromPb(pbValue.item(), config, pool);
+            if (!value) {
+                return {};
+            }
+
+        } else if (pbValue.has_compound_value()) {
+            const pb::CompoundValue pbCompoundValue = pbValue.compound_value();
+            if (pbCompoundValue.has_attr()) {
+                const pb::Attribute& pbAttr = pbCompoundValue.attr();
+                std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak);
+                attr->typeMask = pbAttr.format_flags();
+                for (const pb::Attribute_Symbol& pbSymbol : pbAttr.symbols()) {
+                    Attribute::Symbol symbol;
+                    deserializeItemCommon(pbSymbol, &symbol.symbol);
+                    if (!deserializeReferenceFromPb(pbSymbol.name(), &symbol.symbol)) {
+                        return {};
+                    }
+                    symbol.value = pbSymbol.value();
+                    attr->symbols.push_back(std::move(symbol));
+                }
+                value = std::move(attr);
+
+            } else if (pbCompoundValue.has_style()) {
+                const pb::Style& pbStyle = pbCompoundValue.style();
+                std::unique_ptr<Style> style = util::make_unique<Style>();
+                if (pbStyle.has_parent()) {
+                    style->parent = Reference();
+                    if (!deserializeReferenceFromPb(pbStyle.parent(), &style->parent.value())) {
+                        return {};
+                    }
+
+                    if (pbStyle.has_parent_source()) {
+                        Source parentSource;
+                        deserializeSourceFromPb(pbStyle.parent_source(), *mSourcePool,
+                                                &parentSource);
+                        style->parent.value().setSource(std::move(parentSource));
+                    }
+                }
+
+                for (const pb::Style_Entry& pbEntry : pbStyle.entries()) {
+                    Style::Entry entry;
+                    deserializeItemCommon(pbEntry, &entry.key);
+                    if (!deserializeReferenceFromPb(pbEntry.key(), &entry.key)) {
+                        return {};
+                    }
+
+                    entry.value = deserializeItemFromPb(pbEntry.item(), config, pool);
+                    if (!entry.value) {
+                        return {};
+                    }
+
+                    deserializeItemCommon(pbEntry, entry.value.get());
+                    style->entries.push_back(std::move(entry));
+                }
+                value = std::move(style);
+
+            } else if (pbCompoundValue.has_styleable()) {
+                const pb::Styleable& pbStyleable = pbCompoundValue.styleable();
+                std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
+                for (const pb::Styleable_Entry& pbEntry : pbStyleable.entries()) {
+                    Reference attrRef;
+                    deserializeItemCommon(pbEntry, &attrRef);
+                    deserializeReferenceFromPb(pbEntry.attr(), &attrRef);
+                    styleable->entries.push_back(std::move(attrRef));
+                }
+                value = std::move(styleable);
+
+            } else if (pbCompoundValue.has_array()) {
+                const pb::Array& pbArray = pbCompoundValue.array();
+                std::unique_ptr<Array> array = util::make_unique<Array>();
+                for (const pb::Array_Entry& pbEntry : pbArray.entries()) {
+                    std::unique_ptr<Item> item = deserializeItemFromPb(pbEntry.item(), config,
+                                                                       pool);
+                    if (!item) {
+                        return {};
+                    }
+
+                    deserializeItemCommon(pbEntry, item.get());
+                    array->items.push_back(std::move(item));
+                }
+                value = std::move(array);
+
+            } else if (pbCompoundValue.has_plural()) {
+                const pb::Plural& pbPlural = pbCompoundValue.plural();
+                std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+                for (const pb::Plural_Entry& pbEntry : pbPlural.entries()) {
+                    size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity());
+                    plural->values[pluralIdx] = deserializeItemFromPb(pbEntry.item(), config,
+                                                                      pool);
+                    if (!plural->values[pluralIdx]) {
+                        return {};
+                    }
+
+                    deserializeItemCommon(pbEntry, plural->values[pluralIdx].get());
+                }
+                value = std::move(plural);
+
+            } else {
+                mDiag->error(DiagMessage(mSource) << "unknown compound value");
+                return {};
+            }
+        } else {
+            mDiag->error(DiagMessage(mSource) << "unknown value");
+            return {};
+        }
+
+        assert(value && "forgot to set value");
+
+        value->setWeak(isWeak);
+        deserializeItemCommon(pbValue, value.get());
+        return value;
+    }
+
+    bool deserializeReferenceFromPb(const pb::Reference& pbRef, Reference* outRef) {
+        outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type());
+        outRef->privateReference = pbRef.private_();
+
+        if (!pbRef.has_id() && !pbRef.has_symbol_idx()) {
+            return false;
+        }
+
+        if (pbRef.has_id()) {
+            outRef->id = ResourceId(pbRef.id());
+        }
+
+        if (pbRef.has_symbol_idx()) {
+            StringPiece16 strSymbol = util::getString(*mSymbolPool, pbRef.symbol_idx());
+            ResourceNameRef nameRef;
+            if (!ResourceUtils::parseResourceName(strSymbol, &nameRef, nullptr)) {
+                mDiag->error(DiagMessage(mSource) << "invalid reference name '"
+                             << strSymbol << "'");
+                return false;
+            }
+
+            outRef->name = nameRef.toResourceName();
+        }
+        return true;
+    }
+
+    template <typename T>
+    void deserializeItemCommon(const T& pbItem, Value* outValue) {
+        if (pbItem.has_source()) {
+            Source source;
+            deserializeSourceFromPb(pbItem.source(), *mSourcePool, &source);
+            outValue->setSource(std::move(source));
+        }
+
+        if (pbItem.has_comment()) {
+            outValue->setComment(util::utf8ToUtf16(pbItem.comment()));
+        }
+    }
+
+private:
+    const android::ResStringPool* mValuePool;
+    const android::ResStringPool* mSourcePool;
+    const android::ResStringPool* mSymbolPool;
+    const Source mSource;
+    IDiagnostics* mDiag;
+};
+
+} // namespace
+
+std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
+                                                      const Source& source,
+                                                      IDiagnostics* diag) {
+    std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
+
+    if (!pbTable.has_string_pool()) {
+        diag->error(DiagMessage(source) << "no string pool found");
+        return {};
+    }
+
+    android::ResStringPool valuePool;
+    android::status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
+                                               pbTable.string_pool().data().size());
+    if (result != android::NO_ERROR) {
+        diag->error(DiagMessage(source) << "invalid string pool");
+        return {};
+    }
+
+    android::ResStringPool sourcePool;
+    if (pbTable.has_source_pool()) {
+        result = sourcePool.setTo(pbTable.source_pool().data().data(),
+                                  pbTable.source_pool().data().size());
+        if (result != android::NO_ERROR) {
+            diag->error(DiagMessage(source) << "invalid source pool");
+            return {};
+        }
+    }
+
+    android::ResStringPool symbolPool;
+    if (pbTable.has_symbol_pool()) {
+        result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
+                                  pbTable.symbol_pool().data().size());
+        if (result != android::NO_ERROR) {
+            diag->error(DiagMessage(source) << "invalid symbol pool");
+            return {};
+        }
+    }
+
+    PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool, &symbolPool, source, diag);
+    for (const pb::Package& pbPackage : pbTable.packages()) {
+        if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) {
+            return {};
+        }
+    }
+    return table;
+}
+
+std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFile& pbFile,
+                                                            const Source& source,
+                                                            IDiagnostics* diag) {
+    std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();
+
+    ResourceNameRef nameRef;
+
+    // Need to create an lvalue here so that nameRef can point to something real.
+    std::u16string utf16Name = util::utf8ToUtf16(pbFile.resource_name());
+    if (!ResourceUtils::parseResourceName(utf16Name, &nameRef)) {
+        diag->error(DiagMessage(source) << "invalid resource name in compiled file header: "
+                    << pbFile.resource_name());
+        return {};
+    }
+    file->name = nameRef.toResourceName();
+    file->source.path = pbFile.source_path();
+    deserializeConfigDescriptionFromPb(pbFile.config(), &file->config);
+
+    for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) {
+        // Need to create an lvalue here so that nameRef can point to something real.
+        utf16Name = util::utf8ToUtf16(pbSymbol.resource_name());
+        if (!ResourceUtils::parseResourceName(utf16Name, &nameRef)) {
+            diag->error(DiagMessage(source) << "invalid resource name for exported symbol in "
+                                               "compiled file header: "
+                                            << pbFile.resource_name());
+            return {};
+        }
+        file->exportedSymbols.push_back(
+                SourcedResourceName{ nameRef.toResourceName(), pbSymbol.line_no() });
+    }
+    return file;
+}
+
+CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size) :
+        mIn(static_cast<const uint8_t*>(data), size), mPbFile(),
+        mData(static_cast<const uint8_t*>(data)), mSize(size) {
+}
+
+const pb::CompiledFile* CompiledFileInputStream::CompiledFile() {
+    if (!mPbFile) {
+        std::unique_ptr<pb::CompiledFile> pbFile = util::make_unique<pb::CompiledFile>();
+        uint64_t pbSize = 0u;
+        if (!mIn.ReadLittleEndian64(&pbSize)) {
+            return nullptr;
+        }
+        mIn.PushLimit(static_cast<int>(pbSize));
+        if (!pbFile->ParsePartialFromCodedStream(&mIn)) {
+            return nullptr;
+        }
+
+        const size_t padding = 4 - (pbSize & 0x03);
+        mData += sizeof(uint64_t) + pbSize + padding;
+        mSize -= sizeof(uint64_t) + pbSize + padding;
+        mPbFile = std::move(pbFile);
+    }
+    return mPbFile.get();
+}
+
+const void* CompiledFileInputStream::data() {
+    if (!mPbFile) {
+        if (!CompiledFile()) {
+            return nullptr;
+        }
+    }
+    return mData;
+}
+
+size_t CompiledFileInputStream::size() {
+    if (!mPbFile) {
+        if (!CompiledFile()) {
+            return 0;
+        }
+    }
+    return mSize;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
new file mode 100644
index 0000000..b3d87d8
--- /dev/null
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Resource.h"
+#include "ResourceTable.h"
+#include "StringPool.h"
+#include "ValueVisitor.h"
+#include "proto/ProtoHelpers.h"
+#include "proto/ProtoSerialize.h"
+#include "util/BigBuffer.h"
+
+namespace aapt {
+
+namespace {
+
+class PbSerializerVisitor : public RawValueVisitor {
+public:
+    using RawValueVisitor::visit;
+
+    /**
+     * Constructor to use when expecting to serialize any value.
+     */
+    PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Value* outPbValue) :
+            mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(outPbValue),
+            mOutPbItem(nullptr) {
+    }
+
+    /**
+     * Constructor to use when expecting to serialize an Item.
+     */
+    PbSerializerVisitor(StringPool* sourcePool, StringPool* symbolPool, pb::Item* outPbItem) :
+            mSourcePool(sourcePool), mSymbolPool(symbolPool), mOutPbValue(nullptr),
+            mOutPbItem(outPbItem) {
+    }
+
+    void visit(Reference* ref) override {
+        serializeReferenceToPb(*ref, getPbItem()->mutable_ref());
+    }
+
+    void visit(String* str) override {
+        getPbItem()->mutable_str()->set_idx(str->value.getIndex());
+    }
+
+    void visit(StyledString* str) override {
+        getPbItem()->mutable_str()->set_idx(str->value.getIndex());
+    }
+
+    void visit(FileReference* file) override {
+        getPbItem()->mutable_file()->set_path_idx(file->path.getIndex());
+    }
+
+    void visit(Id* id) override {
+        getPbItem()->mutable_id();
+    }
+
+    void visit(RawString* rawStr) override {
+        getPbItem()->mutable_raw_str()->set_idx(rawStr->value.getIndex());
+    }
+
+    void visit(BinaryPrimitive* prim) override {
+        android::Res_value val = {};
+        prim->flatten(&val);
+
+        pb::Primitive* pbPrim = getPbItem()->mutable_prim();
+        pbPrim->set_type(val.dataType);
+        pbPrim->set_data(val.data);
+    }
+
+    void visitItem(Item* item) override {
+        assert(false && "unimplemented item");
+    }
+
+    void visit(Attribute* attr) override {
+        pb::Attribute* pbAttr = getPbCompoundValue()->mutable_attr();
+        pbAttr->set_format_flags(attr->typeMask);
+        pbAttr->set_min_int(attr->minInt);
+        pbAttr->set_max_int(attr->maxInt);
+
+        for (auto& symbol : attr->symbols) {
+            pb::Attribute_Symbol* pbSymbol = pbAttr->add_symbols();
+            serializeItemCommonToPb(symbol.symbol, pbSymbol);
+            serializeReferenceToPb(symbol.symbol, pbSymbol->mutable_name());
+            pbSymbol->set_value(symbol.value);
+        }
+    }
+
+    void visit(Style* style) override {
+        pb::Style* pbStyle = getPbCompoundValue()->mutable_style();
+        if (style->parent) {
+            serializeReferenceToPb(style->parent.value(), pbStyle->mutable_parent());
+            serializeSourceToPb(style->parent.value().getSource(),
+                                mSourcePool,
+                                pbStyle->mutable_parent_source());
+        }
+
+        for (Style::Entry& entry : style->entries) {
+            pb::Style_Entry* pbEntry = pbStyle->add_entries();
+            serializeReferenceToPb(entry.key, pbEntry->mutable_key());
+
+            pb::Item* pbItem = pbEntry->mutable_item();
+            serializeItemCommonToPb(entry.key, pbEntry);
+            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbItem);
+            entry.value->accept(&subVisitor);
+        }
+    }
+
+    void visit(Styleable* styleable) override {
+        pb::Styleable* pbStyleable = getPbCompoundValue()->mutable_styleable();
+        for (Reference& entry : styleable->entries) {
+            pb::Styleable_Entry* pbEntry = pbStyleable->add_entries();
+            serializeItemCommonToPb(entry, pbEntry);
+            serializeReferenceToPb(entry, pbEntry->mutable_attr());
+        }
+    }
+
+    void visit(Array* array) override {
+        pb::Array* pbArray = getPbCompoundValue()->mutable_array();
+        for (auto& value : array->items) {
+            pb::Array_Entry* pbEntry = pbArray->add_entries();
+            serializeItemCommonToPb(*value, pbEntry);
+            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbEntry->mutable_item());
+            value->accept(&subVisitor);
+        }
+    }
+
+    void visit(Plural* plural) override {
+        pb::Plural* pbPlural = getPbCompoundValue()->mutable_plural();
+        const size_t count = plural->values.size();
+        for (size_t i = 0; i < count; i++) {
+            if (!plural->values[i]) {
+                // No plural value set here.
+                continue;
+            }
+
+            pb::Plural_Entry* pbEntry = pbPlural->add_entries();
+            pbEntry->set_arity(serializePluralEnumToPb(i));
+            pb::Item* pbElement = pbEntry->mutable_item();
+            serializeItemCommonToPb(*plural->values[i], pbEntry);
+            PbSerializerVisitor subVisitor(mSourcePool, mSymbolPool, pbElement);
+            plural->values[i]->accept(&subVisitor);
+        }
+    }
+
+private:
+    pb::Item* getPbItem() {
+        if (mOutPbValue) {
+            return mOutPbValue->mutable_item();
+        }
+        return mOutPbItem;
+    }
+
+    pb::CompoundValue* getPbCompoundValue() {
+        assert(mOutPbValue);
+        return mOutPbValue->mutable_compound_value();
+    }
+
+    template <typename T>
+    void serializeItemCommonToPb(const Item& item, T* pbItem) {
+        serializeSourceToPb(item.getSource(), mSourcePool, pbItem->mutable_source());
+        if (!item.getComment().empty()) {
+            pbItem->set_comment(util::utf16ToUtf8(item.getComment()));
+        }
+    }
+
+    void serializeReferenceToPb(const Reference& ref, pb::Reference* pbRef) {
+        if (ref.id) {
+            pbRef->set_id(ref.id.value().id);
+        } else if (ref.name) {
+            StringPool::Ref symbolRef = mSymbolPool->makeRef(ref.name.value().toString());
+            pbRef->set_symbol_idx(static_cast<uint32_t>(symbolRef.getIndex()));
+        }
+        pbRef->set_private_(ref.privateReference);
+        pbRef->set_type(serializeReferenceTypeToPb(ref.referenceType));
+    }
+
+    StringPool* mSourcePool;
+    StringPool* mSymbolPool;
+    pb::Value* mOutPbValue;
+    pb::Item* mOutPbItem;
+};
+
+} // namespace
+
+std::unique_ptr<pb::ResourceTable> serializeTableToPb(ResourceTable* table) {
+    // We must do this before writing the resources, since the string pool IDs may change.
+    table->stringPool.sort([](const StringPool::Entry& a, const StringPool::Entry& b) -> bool {
+        int diff = a.context.priority - b.context.priority;
+        if (diff < 0) return true;
+        if (diff > 0) return false;
+        diff = a.context.config.compare(b.context.config);
+        if (diff < 0) return true;
+        if (diff > 0) return false;
+        return a.value < b.value;
+    });
+    table->stringPool.prune();
+
+    std::unique_ptr<pb::ResourceTable> pbTable = util::make_unique<pb::ResourceTable>();
+    serializeStringPoolToPb(table->stringPool, pbTable->mutable_string_pool());
+
+    StringPool sourcePool, symbolPool;
+
+    for (auto& package : table->packages) {
+        pb::Package* pbPackage = pbTable->add_packages();
+        if (package->id) {
+            pbPackage->set_package_id(package->id.value());
+        }
+        pbPackage->set_package_name(util::utf16ToUtf8(package->name));
+
+        for (auto& type : package->types) {
+            pb::Type* pbType = pbPackage->add_types();
+            if (type->id) {
+                pbType->set_id(type->id.value());
+            }
+            pbType->set_name(util::utf16ToUtf8(toString(type->type)));
+
+            for (auto& entry : type->entries) {
+                pb::Entry* pbEntry = pbType->add_entries();
+                if (entry->id) {
+                    pbEntry->set_id(entry->id.value());
+                }
+                pbEntry->set_name(util::utf16ToUtf8(entry->name));
+
+                // Write the SymbolStatus struct.
+                pb::SymbolStatus* pbStatus = pbEntry->mutable_symbol_status();
+                pbStatus->set_visibility(serializeVisibilityToPb(entry->symbolStatus.state));
+                serializeSourceToPb(entry->symbolStatus.source, &sourcePool,
+                                    pbStatus->mutable_source());
+                pbStatus->set_comment(util::utf16ToUtf8(entry->symbolStatus.comment));
+
+                for (auto& configValue : entry->values) {
+                    pb::ConfigValue* pbConfigValue = pbEntry->add_config_values();
+                    serializeConfig(configValue->config, pbConfigValue->mutable_config());
+                    if (!configValue->product.empty()) {
+                        pbConfigValue->mutable_config()->set_product(configValue->product);
+                    }
+
+                    pb::Value* pbValue = pbConfigValue->mutable_value();
+                    serializeSourceToPb(configValue->value->getSource(), &sourcePool,
+                                        pbValue->mutable_source());
+                    if (!configValue->value->getComment().empty()) {
+                        pbValue->set_comment(util::utf16ToUtf8(configValue->value->getComment()));
+                    }
+
+                    if (configValue->value->isWeak()) {
+                        pbValue->set_weak(true);
+                    }
+
+                    PbSerializerVisitor visitor(&sourcePool, &symbolPool, pbValue);
+                    configValue->value->accept(&visitor);
+                }
+            }
+        }
+    }
+
+    serializeStringPoolToPb(sourcePool, pbTable->mutable_source_pool());
+    serializeStringPoolToPb(symbolPool, pbTable->mutable_symbol_pool());
+    return pbTable;
+}
+
+std::unique_ptr<pb::CompiledFile> serializeCompiledFileToPb(const ResourceFile& file) {
+    std::unique_ptr<pb::CompiledFile> pbFile = util::make_unique<pb::CompiledFile>();
+    pbFile->set_resource_name(util::utf16ToUtf8(file.name.toString()));
+    pbFile->set_source_path(file.source.path);
+    serializeConfig(file.config, pbFile->mutable_config());
+
+    for (const SourcedResourceName& exported : file.exportedSymbols) {
+        pb::CompiledFile_Symbol* pbSymbol = pbFile->add_exported_symbols();
+        pbSymbol->set_resource_name(util::utf16ToUtf8(exported.name.toString()));
+        pbSymbol->set_line_no(exported.line);
+    }
+    return pbFile;
+}
+
+CompiledFileOutputStream::CompiledFileOutputStream(google::protobuf::io::ZeroCopyOutputStream* out,
+                                                   pb::CompiledFile* pbFile) :
+        mOut(out), mPbFile(pbFile) {
+}
+
+bool CompiledFileOutputStream::ensureFileWritten() {
+    if (mPbFile) {
+        const uint64_t pbSize = mPbFile->ByteSize();
+        mOut.WriteLittleEndian64(pbSize);
+        mPbFile->SerializeWithCachedSizes(&mOut);
+        const size_t padding = 4 - (pbSize & 0x03);
+        if (padding > 0) {
+            uint32_t zero = 0u;
+            mOut.WriteRaw(&zero, padding);
+        }
+        mPbFile = nullptr;
+    }
+    return !mOut.HadError();
+}
+
+bool CompiledFileOutputStream::Write(const void* data, int size) {
+    if (!ensureFileWritten()) {
+        return false;
+    }
+    mOut.WriteRaw(data, size);
+    return !mOut.HadError();
+}
+
+bool CompiledFileOutputStream::Finish() {
+    return ensureFileWritten();
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp
new file mode 100644
index 0000000..70a33f7
--- /dev/null
+++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ResourceTable.h"
+#include "proto/ProtoSerialize.h"
+#include "test/Builders.h"
+#include "test/Common.h"
+#include "test/Context.h"
+
+#include <gtest/gtest.h>
+
+namespace aapt {
+
+TEST(TableProtoSerializer, SerializeSinglePackage) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+    std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder()
+            .setPackageId(u"com.app.a", 0x7f)
+            .addFileReference(u"@com.app.a:layout/main", ResourceId(0x7f020000),
+                              u"res/layout/main.xml")
+            .addReference(u"@com.app.a:layout/other", ResourceId(0x7f020001),
+                          u"@com.app.a:layout/main")
+            .addString(u"@com.app.a:string/text", {}, u"hi")
+            .addValue(u"@com.app.a:id/foo", {}, util::make_unique<Id>())
+            .build();
+
+    Symbol publicSymbol;
+    publicSymbol.state = SymbolState::kPublic;
+    ASSERT_TRUE(table->setSymbolState(test::parseNameOrDie(u"@com.app.a:layout/main"),
+                                      ResourceId(0x7f020000),
+                                      publicSymbol, context->getDiagnostics()));
+
+    Id* id = test::getValue<Id>(table.get(), u"@com.app.a:id/foo");
+    ASSERT_NE(nullptr, id);
+
+    // Make a plural.
+    std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+    plural->values[Plural::One] = util::make_unique<String>(table->stringPool.makeRef(u"one"));
+    ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:plurals/hey"),
+                                   ConfigDescription{}, std::string(), std::move(plural),
+                                   context->getDiagnostics()));
+
+    // Make a resource with different products.
+    ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:integer/one"),
+                                   test::parseConfigOrDie("land"), std::string(),
+                                   test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 123u),
+                                   context->getDiagnostics()));
+    ASSERT_TRUE(table->addResource(test::parseNameOrDie(u"@com.app.a:integer/one"),
+                                       test::parseConfigOrDie("land"), std::string("tablet"),
+                                       test::buildPrimitive(android::Res_value::TYPE_INT_DEC, 321u),
+                                       context->getDiagnostics()));
+
+    std::unique_ptr<pb::ResourceTable> pbTable = serializeTableToPb(table.get());
+    ASSERT_NE(nullptr, pbTable);
+
+    std::unique_ptr<ResourceTable> newTable = deserializeTableFromPb(*pbTable,
+                                                                     Source{ "test" },
+                                                                     context->getDiagnostics());
+    ASSERT_NE(nullptr, newTable);
+
+    Id* newId = test::getValue<Id>(newTable.get(), u"@com.app.a:id/foo");
+    ASSERT_NE(nullptr, newId);
+    EXPECT_EQ(id->isWeak(), newId->isWeak());
+
+    Maybe<ResourceTable::SearchResult> result = newTable->findResource(
+            test::parseNameOrDie(u"@com.app.a:layout/main"));
+    AAPT_ASSERT_TRUE(result);
+    EXPECT_EQ(SymbolState::kPublic, result.value().type->symbolStatus.state);
+    EXPECT_EQ(SymbolState::kPublic, result.value().entry->symbolStatus.state);
+
+    // Find the product-dependent values
+    BinaryPrimitive* prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
+            newTable.get(), u"@com.app.a:integer/one", test::parseConfigOrDie("land"), "");
+    ASSERT_NE(nullptr, prim);
+    EXPECT_EQ(123u, prim->value.data);
+
+    prim = test::getValueForConfigAndProduct<BinaryPrimitive>(
+            newTable.get(), u"@com.app.a:integer/one", test::parseConfigOrDie("land"), "tablet");
+    ASSERT_NE(nullptr, prim);
+    EXPECT_EQ(321u, prim->value.data);
+}
+
+TEST(TableProtoSerializer, SerializeFileHeader) {
+    std::unique_ptr<IAaptContext> context = test::ContextBuilder().build();
+
+    ResourceFile f;
+    f.config = test::parseConfigOrDie("hdpi-v9");
+    f.name = test::parseNameOrDie(u"@com.app.a:layout/main");
+    f.source.path = "res/layout-hdpi-v9/main.xml";
+    f.exportedSymbols.push_back(SourcedResourceName{ test::parseNameOrDie(u"@+id/unchecked"), 23u });
+
+    const std::string expectedData = "1234";
+
+    std::unique_ptr<pb::CompiledFile> pbFile = serializeCompiledFileToPb(f);
+
+    std::string outputStr;
+    {
+        google::protobuf::io::StringOutputStream outStream(&outputStr);
+        CompiledFileOutputStream outFileStream(&outStream, pbFile.get());
+
+        ASSERT_TRUE(outFileStream.Write(expectedData.data(), expectedData.size()));
+        ASSERT_TRUE(outFileStream.Finish());
+    }
+
+    CompiledFileInputStream inFileStream(outputStr.data(), outputStr.size());
+    const pb::CompiledFile* newPbFile = inFileStream.CompiledFile();
+    ASSERT_NE(nullptr, newPbFile);
+
+    std::unique_ptr<ResourceFile> file = deserializeCompiledFileFromPb(*newPbFile, Source{ "test" },
+                                                                       context->getDiagnostics());
+    ASSERT_NE(nullptr, file);
+
+    std::string actualData((const char*)inFileStream.data(), inFileStream.size());
+    EXPECT_EQ(expectedData, actualData);
+    EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(inFileStream.data()) & 0x03);
+
+    ASSERT_EQ(1u, file->exportedSymbols.size());
+    EXPECT_EQ(test::parseNameOrDie(u"@+id/unchecked"), file->exportedSymbols[0].name);
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index 579a46e..834caf8 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -104,8 +104,8 @@
                                    const ConfigDescription& config,
                                    std::unique_ptr<Value> value) {
         ResourceName resName = parseNameOrDie(name);
-        bool result = mTable->addResourceAllowMangled(resName, id, config, std::move(value),
-                                                      &mDiagnostics);
+        bool result = mTable->addResourceAllowMangled(resName, id, config, std::string(),
+                                                      std::move(value), &mDiagnostics);
         assert(result);
         return *this;
     }
@@ -132,6 +132,14 @@
     return reference;
 }
 
+inline std::unique_ptr<BinaryPrimitive> buildPrimitive(uint8_t type, uint32_t data) {
+    android::Res_value value = {};
+    value.size = sizeof(value);
+    value.dataType = type;
+    value.data = data;
+    return util::make_unique<BinaryPrimitive>(value);
+}
+
 template <typename T>
 class ValueBuilder {
 private:
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 51e2dd4..348c32a 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -52,6 +52,11 @@
     void note(const DiagMessage& message) override {}
 };
 
+inline IDiagnostics* getDiagnostics() {
+    static DummyDiagnosticsImpl diag;
+    return &diag;
+}
+
 inline ResourceName parseNameOrDie(const StringPiece16& str) {
     ResourceNameRef ref;
     bool result = ResourceUtils::tryParseReference(str, &ref);
@@ -66,23 +71,25 @@
     return config;
 }
 
-template <typename T> T* getValueForConfig(ResourceTable* table, const StringPiece16& resName,
-                                           const ConfigDescription& config) {
+template <typename T> T* getValueForConfigAndProduct(ResourceTable* table,
+                                                     const StringPiece16& resName,
+                                                     const ConfigDescription& config,
+                                                     const StringPiece& product) {
     Maybe<ResourceTable::SearchResult> result = table->findResource(parseNameOrDie(resName));
     if (result) {
-        ResourceEntry* entry = result.value().entry;
-        auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), config,
-                                     [](const ResourceConfigValue& a, const ConfigDescription& b)
-                                             -> bool {
-                                         return a.config < b;
-                                     });
-        if (iter != entry->values.end() && iter->config == config) {
-            return valueCast<T>(iter->value.get());
+        ResourceConfigValue* configValue = result.value().entry->findValue(config, product);
+        if (configValue) {
+            return valueCast<T>(configValue->value.get());
         }
     }
     return nullptr;
 }
 
+template <typename T> T* getValueForConfig(ResourceTable* table, const StringPiece16& resName,
+                                           const ConfigDescription& config) {
+    return getValueForConfigAndProduct<T>(table, resName, config, {});
+}
+
 template <typename T> T* getValue(ResourceTable* table, const StringPiece16& resName) {
     return getValueForConfig<T>(table, resName, {});
 }
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index 6b7a63cf..33b505e 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -19,8 +19,6 @@
 #include "ResourceValues.h"
 #include "Source.h"
 #include "ValueVisitor.h"
-
-#include "flatten/ResourceTypeExtensions.h"
 #include "unflatten/BinaryResourceParser.h"
 #include "unflatten/ResChunkPullParser.h"
 #include "util/Util.h"
@@ -36,6 +34,8 @@
 
 using namespace android;
 
+namespace {
+
 /*
  * Visitor that converts a reference's resource ID to a resource name,
  * given a mapping from resource ID to resource name.
@@ -66,6 +66,8 @@
     }
 };
 
+} // namespace
+
 BinaryResourceParser::BinaryResourceParser(IAaptContext* context, ResourceTable* table,
                                            const Source& source, const void* data, size_t len) :
         mContext(context), mTable(table), mSource(source), mData(data), mDataLen(len) {
@@ -97,106 +99,6 @@
     return !error;
 }
 
-Maybe<Reference> BinaryResourceParser::getSymbol(const void* data) {
-    if (!mSymbolEntries || mSymbolEntryCount == 0) {
-        return {};
-    }
-
-    if ((uintptr_t) data < (uintptr_t) mData) {
-        return {};
-    }
-
-    // We only support 32 bit offsets right now.
-    const uintptr_t offset = (uintptr_t) data - (uintptr_t) mData;
-    if (offset > std::numeric_limits<uint32_t>::max()) {
-        return {};
-    }
-
-    for (size_t i = 0; i < mSymbolEntryCount; i++) {
-        if (util::deviceToHost32(mSymbolEntries[i].offset) == offset) {
-            // This offset is a symbol!
-            const StringPiece16 str = util::getString(
-                    mSymbolPool, util::deviceToHost32(mSymbolEntries[i].name.index));
-
-            ResourceNameRef nameRef;
-            bool privateRef = false;
-            if (!ResourceUtils::parseResourceName(str, &nameRef, &privateRef)) {
-                return {};
-            }
-
-            // Since we scan the symbol table in order, we can start looking for the
-            // next symbol from this point.
-            mSymbolEntryCount -= i + 1;
-            mSymbolEntries += i + 1;
-
-            Reference ref(nameRef);
-            ref.privateReference = privateRef;
-            return Maybe<Reference>(std::move(ref));
-        }
-    }
-    return {};
-}
-
-/**
- * Parses the SymbolTable_header, which is present on non-final resource tables
- * after the compile phase.
- *
- * | SymbolTable_header |
- * |--------------------|
- * |SymbolTable_entry 0 |
- * |SymbolTable_entry 1 |
- * | ...                |
- * |SymbolTable_entry n |
- * |--------------------|
- *
- */
-bool BinaryResourceParser::parseSymbolTable(const ResChunk_header* chunk) {
-    const SymbolTable_header* header = convertTo<SymbolTable_header>(chunk);
-    if (!header) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt SymbolTable_header");
-        return false;
-    }
-
-    const uint32_t entrySizeBytes =
-            util::deviceToHost32(header->count) * sizeof(SymbolTable_entry);
-    if (entrySizeBytes > getChunkDataLen(&header->header)) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "SymbolTable_header data section too long");
-        return false;
-    }
-
-    mSymbolEntries = (const SymbolTable_entry*) getChunkData(&header->header);
-    mSymbolEntryCount = util::deviceToHost32(header->count);
-
-    // Skip over the symbol entries and parse the StringPool chunk that should be next.
-    ResChunkPullParser parser(getChunkData(&header->header) + entrySizeBytes,
-                              getChunkDataLen(&header->header) - entrySizeBytes);
-    if (!ResChunkPullParser::isGoodEvent(parser.next())) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "failed to parse chunk in SymbolTable: "
-                                          << parser.getLastError());
-        return false;
-    }
-
-    const ResChunk_header* nextChunk = parser.getChunk();
-    if (util::deviceToHost16(nextChunk->type) != android::RES_STRING_POOL_TYPE) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "expected string pool in SymbolTable but got "
-                                          << "chunk of type "
-                                          << (int) util::deviceToHost16(nextChunk->type));
-        return false;
-    }
-
-    if (mSymbolPool.setTo(nextChunk, util::deviceToHost32(nextChunk->size)) != NO_ERROR) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt string pool in SymbolTable: "
-                                          << mSymbolPool.getError());
-        return false;
-    }
-    return true;
-}
-
 /**
  * Parses the resource table, which contains all the packages, types, and entries.
  */
@@ -230,24 +132,6 @@
             }
             break;
 
-        case RES_TABLE_SYMBOL_TABLE_TYPE:
-            if (!parseSymbolTable(parser.getChunk())) {
-                return false;
-            }
-            break;
-
-        case RES_TABLE_SOURCE_POOL_TYPE: {
-            status_t err = mSourcePool.setTo(getChunkData(parser.getChunk()),
-                                             getChunkDataLen(parser.getChunk()));
-            if (err != NO_ERROR) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "corrupt source string pool in ResTable: "
-                                                  << mSourcePool.getError());
-                return false;
-            }
-            break;
-        }
-
         case android::RES_TABLE_PACKAGE_TYPE:
             if (!parsePackage(parser.getChunk())) {
                 return false;
@@ -350,12 +234,6 @@
             }
             break;
 
-        case RES_TABLE_PUBLIC_TYPE:
-            if (!parsePublic(package, parser.getChunk())) {
-                return false;
-            }
-            break;
-
         default:
             mContext->getDiagnostics()
                     ->warn(DiagMessage(mSource)
@@ -375,97 +253,7 @@
     // Now go through the table and change local resource ID references to
     // symbolic references.
     ReferenceIdToNameVisitor visitor(&mIdIndex);
-    for (auto& package : mTable->packages) {
-        for (auto& type : package->types) {
-            for (auto& entry : type->entries) {
-                for (auto& configValue : entry->values) {
-                    configValue.value->accept(&visitor);
-                }
-            }
-        }
-    }
-    return true;
-}
-
-bool BinaryResourceParser::parsePublic(const ResourceTablePackage* package,
-                                       const ResChunk_header* chunk) {
-    const Public_header* header = convertTo<Public_header>(chunk);
-    if (!header) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "corrupt Public_header chunk");
-        return false;
-    }
-
-    if (header->typeId == 0) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "invalid type ID "
-                                          << (int) header->typeId);
-        return false;
-    }
-
-    StringPiece16 typeStr16 = util::getString(mTypePool, header->typeId - 1);
-    const ResourceType* parsedType = parseResourceType(typeStr16);
-    if (!parsedType) {
-        mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                          << "invalid type '" << typeStr16 << "'");
-        return false;
-    }
-
-    const uintptr_t chunkEnd = (uintptr_t) chunk + util::deviceToHost32(chunk->size);
-    const Public_entry* entry = (const Public_entry*) getChunkData(&header->header);
-    for (uint32_t i = 0; i < util::deviceToHost32(header->count); i++) {
-        if ((uintptr_t) entry + sizeof(*entry) > chunkEnd) {
-            mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                              << "Public_entry data section is too long");
-            return false;
-        }
-
-        const ResourceId resId(package->id.value(), header->typeId,
-                               util::deviceToHost16(entry->entryId));
-
-        const ResourceName name(package->name, *parsedType,
-                                util::getString(mKeyPool, entry->key.index).toString());
-
-        Symbol symbol;
-        if (mSourcePool.getError() == NO_ERROR) {
-            symbol.source.path = util::utf16ToUtf8(util::getString(
-                    mSourcePool, util::deviceToHost32(entry->source.path.index)));
-            symbol.source.line = util::deviceToHost32(entry->source.line);
-        }
-
-        StringPiece16 comment = util::getString(mSourcePool,
-                                                util::deviceToHost32(entry->source.comment.index));
-        if (!comment.empty()) {
-            symbol.comment = comment.toString();
-        }
-
-        switch (util::deviceToHost16(entry->state)) {
-        case Public_entry::kPrivate:
-            symbol.state = SymbolState::kPrivate;
-            break;
-
-        case Public_entry::kPublic:
-            symbol.state = SymbolState::kPublic;
-            break;
-
-        case Public_entry::kUndefined:
-            symbol.state = SymbolState::kUndefined;
-            break;
-        }
-
-        if (!mTable->setSymbolStateAllowMangled(name, resId, symbol, mContext->getDiagnostics())) {
-            return false;
-        }
-
-        // Add this resource name->id mapping to the index so
-        // that we can resolve all ID references to name references.
-        auto cacheIter = mIdIndex.find(resId);
-        if (cacheIter == mIdIndex.end()) {
-            mIdIndex.insert({ resId, name });
-        }
-
-        entry++;
-    }
+    visitAllValuesInTable(mTable, &visitor);
     return true;
 }
 
@@ -545,25 +333,12 @@
         const ResourceId resId(package->id.value(), type->id, static_cast<uint16_t>(it.index()));
 
         std::unique_ptr<Value> resourceValue;
-        const ResTable_entry_source* sourceBlock = nullptr;
-
         if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
             const ResTable_map_entry* mapEntry = static_cast<const ResTable_map_entry*>(entry);
-            if (util::deviceToHost32(mapEntry->size) - sizeof(*mapEntry) == sizeof(*sourceBlock)) {
-                const uint8_t* data = (const uint8_t*) mapEntry;
-                data += util::deviceToHost32(mapEntry->size) - sizeof(*sourceBlock);
-                sourceBlock = (const ResTable_entry_source*) data;
-            }
 
             // TODO(adamlesinski): Check that the entry count is valid.
             resourceValue = parseMapEntry(name, config, mapEntry);
         } else {
-            if (util::deviceToHost32(entry->size) - sizeof(*entry) == sizeof(*sourceBlock)) {
-                const uint8_t* data = (const uint8_t*) entry;
-                data += util::deviceToHost32(entry->size) - sizeof(*sourceBlock);
-                sourceBlock = (const ResTable_entry_source*) data;
-            }
-
             const Res_value* value = (const Res_value*)(
                     (const uint8_t*) entry + util::deviceToHost32(entry->size));
             resourceValue = parseValue(name, config, value, entry->flags);
@@ -577,31 +352,7 @@
             return false;
         }
 
-        Source source = mSource;
-        if (sourceBlock) {
-            StringPiece path = util::getString8(mSourcePool,
-                                                util::deviceToHost32(sourceBlock->path.index));
-            if (!path.empty()) {
-                source.path = path.toString();
-            }
-            source.line = util::deviceToHost32(sourceBlock->line);
-
-            if (Style* style = valueCast<Style>(resourceValue.get())) {
-                // The parent's source is the same as the resource itself, set it here.
-                if (style->parent) {
-                    style->parent.value().setSource(source);
-                }
-            }
-        }
-
-        StringPiece16 comment = util::getString(mSourcePool,
-                                                util::deviceToHost32(sourceBlock->comment.index));
-        if (!comment.empty()) {
-            resourceValue->setComment(comment);
-        }
-
-        resourceValue->setSource(source);
-        if (!mTable->addResourceAllowMangled(name, config, std::move(resourceValue),
+        if (!mTable->addResourceAllowMangled(name, config, {}, std::move(resourceValue),
                                              mContext->getDiagnostics())) {
             return false;
         }
@@ -674,26 +425,15 @@
         const Reference::Type type = (value->dataType == Res_value::TYPE_REFERENCE) ?
                 Reference::Type::kResource : Reference::Type::kAttribute;
 
-        if (data != 0) {
-            // This is a normal reference.
-            return util::make_unique<Reference>(data, type);
+        if (data == 0) {
+            // A reference of 0, must be the magic @null reference.
+            Res_value nullType = {};
+            nullType.dataType = Res_value::TYPE_REFERENCE;
+            return util::make_unique<BinaryPrimitive>(nullType);
         }
 
-        // This reference has an invalid ID. Check if it is an unresolved symbol.
-        if (Maybe<Reference> ref = getSymbol(&value->data)) {
-            ref.value().referenceType = type;
-            return util::make_unique<Reference>(std::move(ref.value()));
-        }
-
-        // This is not an unresolved symbol, so it must be the magic @null reference.
-        Res_value nullType = {};
-        nullType.dataType = Res_value::TYPE_REFERENCE;
-        return util::make_unique<BinaryPrimitive>(nullType);
-    }
-
-    if (value->dataType == ExtendedTypes::TYPE_RAW_STRING) {
-        return util::make_unique<RawString>(mTable->stringPool.makeRef(
-                util::getString(mValuePool, data), StringPool::Context{ 1, config }));
+        // This is a normal reference.
+        return util::make_unique<Reference>(data, type);
     }
 
     // Treat this as a raw binary primitive.
@@ -712,8 +452,6 @@
             return parseAttr(name, config, map);
         case ResourceType::kArray:
             return parseArray(name, config, map);
-        case ResourceType::kStyleable:
-            return parseStyleable(name, config, map);
         case ResourceType::kPlurals:
             return parsePlural(name, config, map);
         default:
@@ -727,51 +465,23 @@
                                                         const ConfigDescription& config,
                                                         const ResTable_map_entry* map) {
     std::unique_ptr<Style> style = util::make_unique<Style>();
-    if (util::deviceToHost32(map->parent.ident) == 0) {
-        // The parent is either not set or it is an unresolved symbol.
-        // Check to see if it is a symbol.
-        style->parent = getSymbol(&map->parent.ident);
-
-    } else {
-         // The parent is a regular reference to a resource.
+    if (util::deviceToHost32(map->parent.ident) != 0) {
+        // The parent is a regular reference to a resource.
         style->parent = Reference(util::deviceToHost32(map->parent.ident));
     }
 
     for (const ResTable_map& mapEntry : map) {
         if (Res_INTERNALID(util::deviceToHost32(mapEntry.name.ident))) {
-            if (style->entries.empty()) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "out-of-sequence meta data in style");
-                return {};
-            }
-            collectMetaData(mapEntry, &style->entries.back().key);
             continue;
         }
 
-        style->entries.emplace_back();
-        Style::Entry& styleEntry = style->entries.back();
-
-        if (util::deviceToHost32(mapEntry.name.ident) == 0) {
-            // The map entry's key (attribute) is not set. This must be
-            // a symbol reference, so resolve it.
-            Maybe<Reference> symbol = getSymbol(&mapEntry.name.ident);
-            if (!symbol) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "unresolved style attribute");
-                return {};
-            }
-            styleEntry.key = std::move(symbol.value());
-
-        } else {
-            // The map entry's key (attribute) is a regular reference.
-            styleEntry.key.id = ResourceId(util::deviceToHost32(mapEntry.name.ident));
-        }
-
-        // Parse the attribute's value.
+        Style::Entry styleEntry;
+        styleEntry.key = Reference(util::deviceToHost32(mapEntry.name.ident));
         styleEntry.value = parseValue(name, config, &mapEntry.value, 0);
         if (!styleEntry.value) {
             return {};
         }
+        style->entries.push_back(std::move(styleEntry));
     }
     return style;
 }
@@ -807,22 +517,7 @@
         if (attr->typeMask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
             Attribute::Symbol symbol;
             symbol.value = util::deviceToHost32(mapEntry.value.data);
-            if (util::deviceToHost32(mapEntry.name.ident) == 0) {
-                // The map entry's key (id) is not set. This must be
-                // a symbol reference, so resolve it.
-                Maybe<Reference> ref = getSymbol(&mapEntry.name.ident);
-                if (!ref) {
-                    mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                      << "unresolved attribute symbol");
-                    return {};
-                }
-                symbol.symbol = std::move(ref.value());
-
-            } else {
-                // The map entry's key (id) is a regular reference.
-                symbol.symbol.id = ResourceId(util::deviceToHost32(mapEntry.name.ident));
-            }
-
+            symbol.symbol = Reference(util::deviceToHost32(mapEntry.name.ident));
             attr->symbols.push_back(std::move(symbol));
         }
     }
@@ -831,115 +526,26 @@
     return attr;
 }
 
-static bool isMetaDataEntry(const ResTable_map& mapEntry) {
-    switch (util::deviceToHost32(mapEntry.name.ident)) {
-    case ExtendedResTableMapTypes::ATTR_SOURCE_PATH:
-    case ExtendedResTableMapTypes::ATTR_SOURCE_LINE:
-    case ExtendedResTableMapTypes::ATTR_COMMENT:
-        return true;
-    }
-    return false;
-}
-
-bool BinaryResourceParser::collectMetaData(const ResTable_map& mapEntry, Value* value) {
-    switch (util::deviceToHost32(mapEntry.name.ident)) {
-    case ExtendedResTableMapTypes::ATTR_SOURCE_PATH:
-        value->setSource(Source(util::getString8(mSourcePool,
-                                                 util::deviceToHost32(mapEntry.value.data))));
-        return true;
-        break;
-
-    case ExtendedResTableMapTypes::ATTR_SOURCE_LINE:
-        value->setSource(value->getSource().withLine(util::deviceToHost32(mapEntry.value.data)));
-        return true;
-        break;
-
-    case ExtendedResTableMapTypes::ATTR_COMMENT:
-        value->setComment(util::getString(mSourcePool, util::deviceToHost32(mapEntry.value.data)));
-        return true;
-        break;
-    }
-    return false;
-}
-
 std::unique_ptr<Array> BinaryResourceParser::parseArray(const ResourceNameRef& name,
                                                         const ConfigDescription& config,
                                                         const ResTable_map_entry* map) {
     std::unique_ptr<Array> array = util::make_unique<Array>();
-    Source source;
     for (const ResTable_map& mapEntry : map) {
-        if (isMetaDataEntry(mapEntry)) {
-            if (array->items.empty()) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "out-of-sequence meta data in array");
-                return {};
-            }
-            collectMetaData(mapEntry, array->items.back().get());
-            continue;
-        }
-
         array->items.push_back(parseValue(name, config, &mapEntry.value, 0));
     }
     return array;
 }
 
-std::unique_ptr<Styleable> BinaryResourceParser::parseStyleable(const ResourceNameRef& name,
-                                                                const ConfigDescription& config,
-                                                                const ResTable_map_entry* map) {
-    std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
-    for (const ResTable_map& mapEntry : map) {
-        if (isMetaDataEntry(mapEntry)) {
-            if (styleable->entries.empty()) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "out-of-sequence meta data in styleable");
-                return {};
-            }
-            collectMetaData(mapEntry, &styleable->entries.back());
-            continue;
-        }
-
-        if (util::deviceToHost32(mapEntry.name.ident) == 0) {
-            // The map entry's key (attribute) is not set. This must be
-            // a symbol reference, so resolve it.
-            Maybe<Reference> ref = getSymbol(&mapEntry.name.ident);
-            if (!ref) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "unresolved styleable symbol");
-                return {};
-            }
-            styleable->entries.emplace_back(std::move(ref.value()));
-
-        } else {
-            // The map entry's key (attribute) is a regular reference.
-            styleable->entries.emplace_back(util::deviceToHost32(mapEntry.name.ident));
-        }
-    }
-    return styleable;
-}
-
 std::unique_ptr<Plural> BinaryResourceParser::parsePlural(const ResourceNameRef& name,
                                                           const ConfigDescription& config,
                                                           const ResTable_map_entry* map) {
     std::unique_ptr<Plural> plural = util::make_unique<Plural>();
-    Item* lastEntry = nullptr;
     for (const ResTable_map& mapEntry : map) {
-        if (isMetaDataEntry(mapEntry)) {
-            if (!lastEntry) {
-                mContext->getDiagnostics()->error(DiagMessage(mSource)
-                                                  << "out-of-sequence meta data in plural");
-                return {};
-            }
-            collectMetaData(mapEntry, lastEntry);
-            continue;
-        }
-
         std::unique_ptr<Item> item = parseValue(name, config, &mapEntry.value, 0);
         if (!item) {
             return {};
         }
 
-        lastEntry = item.get();
-
         switch (util::deviceToHost32(mapEntry.name.ident)) {
             case ResTable_map::ATTR_ZERO:
                 plural->values[Plural::Zero] = std::move(item);
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.h b/tools/aapt2/unflatten/BinaryResourceParser.h
index 0745a59..12bc13d 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.h
+++ b/tools/aapt2/unflatten/BinaryResourceParser.h
@@ -55,14 +55,8 @@
     bool parse();
 
 private:
-    // Helper method to retrieve the symbol name for a given table offset specified
-    // as a pointer.
-    Maybe<Reference> getSymbol(const void* data);
-
     bool parseTable(const android::ResChunk_header* chunk);
-    bool parseSymbolTable(const android::ResChunk_header* chunk);
     bool parsePackage(const android::ResChunk_header* chunk);
-    bool parsePublic(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
     bool parseTypeSpec(const android::ResChunk_header* chunk);
     bool parseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
 
@@ -87,10 +81,6 @@
                                         const ConfigDescription& config,
                                         const android::ResTable_map_entry* map);
 
-    std::unique_ptr<Styleable> parseStyleable(const ResourceNameRef& name,
-                                              const ConfigDescription& config,
-                                              const android::ResTable_map_entry* map);
-
     /**
      * If the mapEntry is a special type that denotes meta data (source, comment), then it is
      * read and added to the Value.
@@ -106,23 +96,6 @@
     const void* mData;
     const size_t mDataLen;
 
-    // The array of symbol entries. Each element points to an offset
-    // in the table and an index into the symbol table string pool.
-    const SymbolTable_entry* mSymbolEntries = nullptr;
-
-    // Number of symbol entries.
-    size_t mSymbolEntryCount = 0;
-
-    // The symbol table string pool. Holds the names of symbols
-    // referenced in this table but not defined nor resolved to an
-    // ID.
-    android::ResStringPool mSymbolPool;
-
-    // The source string pool. Resource entries may have an extra
-    // field that points into this string pool, which denotes where
-    // the resource was parsed from originally.
-    android::ResStringPool mSourcePool;
-
     // The standard value string pool for resource values.
     android::ResStringPool mValuePool;
 
diff --git a/tools/aapt2/unflatten/FileExportHeaderReader.h b/tools/aapt2/unflatten/FileExportHeaderReader.h
deleted file mode 100644
index e552ea1..0000000
--- a/tools/aapt2/unflatten/FileExportHeaderReader.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AAPT_UNFLATTEN_FILEEXPORTHEADERREADER_H
-#define AAPT_UNFLATTEN_FILEEXPORTHEADERREADER_H
-
-#include "ResChunkPullParser.h"
-#include "Resource.h"
-#include "ResourceUtils.h"
-
-#include "flatten/ResourceTypeExtensions.h"
-#include "util/StringPiece.h"
-#include "util/Util.h"
-
-#include <androidfw/ResourceTypes.h>
-#include <sstream>
-#include <string>
-
-namespace aapt {
-
-static ssize_t parseFileExportHeaderImpl(const void* data, const size_t len,
-                                         const FileExport_header** outFileExport,
-                                         const ExportedSymbol** outExportedSymbolIndices,
-                                         android::ResStringPool* outStringPool,
-                                         std::string* outError) {
-    ResChunkPullParser parser(data, len);
-    if (!ResChunkPullParser::isGoodEvent(parser.next())) {
-        if (outError) *outError = parser.getLastError();
-        return -1;
-    }
-
-    if (util::deviceToHost16(parser.getChunk()->type) != RES_FILE_EXPORT_TYPE) {
-        if (outError) *outError = "no FileExport_header found";
-        return -1;
-    }
-
-    const FileExport_header* fileExport = convertTo<FileExport_header>(parser.getChunk());
-    if (!fileExport) {
-        if (outError) *outError = "corrupt FileExport_header";
-        return -1;
-    }
-
-    if (memcmp(fileExport->magic, "AAPT", sizeof(fileExport->magic)) != 0) {
-        if (outError) *outError = "invalid magic value";
-        return -1;
-    }
-
-    const size_t exportedSymbolCount = util::deviceToHost32(fileExport->exportedSymbolCount);
-
-    // Verify that we have enough space for all those symbols.
-    size_t dataLen = getChunkDataLen(&fileExport->header);
-    if (exportedSymbolCount > dataLen / sizeof(ExportedSymbol)) {
-        if (outError) *outError = "too many symbols";
-        return -1;
-    }
-
-    const size_t symbolIndicesSize = exportedSymbolCount * sizeof(ExportedSymbol);
-
-    const void* strPoolData = getChunkData(&fileExport->header) + symbolIndicesSize;
-    const size_t strPoolDataLen = dataLen - symbolIndicesSize;
-    if (outStringPool->setTo(strPoolData, strPoolDataLen, false) != android::NO_ERROR) {
-        if (outError) *outError = "corrupt string pool";
-        return -1;
-    }
-
-    *outFileExport = fileExport;
-    *outExportedSymbolIndices = (const ExportedSymbol*) getChunkData(
-            &fileExport->header);
-    return util::deviceToHost16(fileExport->header.headerSize) + symbolIndicesSize +
-            outStringPool->bytes();
-}
-
-static ssize_t getWrappedDataOffset(const void* data, size_t len, std::string* outError) {
-    const FileExport_header* header = nullptr;
-    const ExportedSymbol* entries = nullptr;
-    android::ResStringPool pool;
-    return parseFileExportHeaderImpl(data, len, &header, &entries, &pool, outError);
-}
-
-/**
- * Reads the FileExport_header and populates outRes with the values in that header.
- */
-static ssize_t unwrapFileExportHeader(const void* data, size_t len, ResourceFile* outRes,
-                                      std::string* outError) {
-
-    const FileExport_header* fileExport = nullptr;
-    const ExportedSymbol* entries = nullptr;
-    android::ResStringPool symbolPool;
-    const ssize_t offset = parseFileExportHeaderImpl(data, len, &fileExport, &entries, &symbolPool,
-                                                     outError);
-    if (offset < 0) {
-        return offset;
-    }
-
-    const size_t exportedSymbolCount = util::deviceToHost32(fileExport->exportedSymbolCount);
-    outRes->exportedSymbols.clear();
-    outRes->exportedSymbols.reserve(exportedSymbolCount);
-
-    for (size_t i = 0; i < exportedSymbolCount; i++) {
-        const StringPiece16 str = util::getString(symbolPool,
-                                                  util::deviceToHost32(entries[i].name.index));
-        StringPiece16 packageStr, typeStr, entryStr;
-        ResourceUtils::extractResourceName(str, &packageStr, &typeStr, &entryStr);
-        const ResourceType* resType = parseResourceType(typeStr);
-        if (!resType || entryStr.empty()) {
-            if (outError) {
-                std::stringstream errorStr;
-                errorStr << "invalid exported symbol at index="
-                         << util::deviceToHost32(entries[i].name.index)
-                         << " (" << str << ")";
-                *outError = errorStr.str();
-            }
-            return -1;
-        }
-
-        outRes->exportedSymbols.push_back(SourcedResourceName{
-                ResourceName{ packageStr.toString(), *resType, entryStr.toString() },
-                util::deviceToHost32(entries[i].line) });
-    }
-
-    const StringPiece16 str = util::getString(symbolPool,
-                                              util::deviceToHost32(fileExport->name.index));
-    StringPiece16 packageStr, typeStr, entryStr;
-    ResourceUtils::extractResourceName(str, &packageStr, &typeStr, &entryStr);
-    const ResourceType* resType = parseResourceType(typeStr);
-    if (!resType || entryStr.empty()) {
-        if (outError) {
-            std::stringstream errorStr;
-            errorStr << "invalid resource name at index="
-                     << util::deviceToHost32(fileExport->name.index)
-                     << " (" << str << ")";
-            *outError = errorStr.str();
-        }
-        return -1;
-    }
-
-    outRes->name = ResourceName{ packageStr.toString(), *resType, entryStr.toString() };
-    outRes->source.path = util::utf16ToUtf8(
-            util::getString(symbolPool, util::deviceToHost32(fileExport->source.index)));
-    outRes->config.copyFromDtoH(fileExport->config);
-    return offset;
-}
-
-} // namespace aapt
-
-#endif /* AAPT_UNFLATTEN_FILEEXPORTHEADERREADER_H */
diff --git a/tools/aapt2/unflatten/FileExportHeaderReader_test.cpp b/tools/aapt2/unflatten/FileExportHeaderReader_test.cpp
deleted file mode 100644
index a76c83b..0000000
--- a/tools/aapt2/unflatten/FileExportHeaderReader_test.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "Resource.h"
-
-#include "flatten/FileExportWriter.h"
-#include "unflatten/FileExportHeaderReader.h"
-#include "util/BigBuffer.h"
-#include "util/Util.h"
-
-#include "test/Common.h"
-
-#include <gtest/gtest.h>
-
-namespace aapt {
-
-TEST(FileExportHeaderReaderTest, ReadHeaderWithNoSymbolExports) {
-    ResourceFile resFile = {
-            test::parseNameOrDie(u"@android:layout/main.xml"),
-            test::parseConfigOrDie("sw600dp-v4"),
-            Source{ "res/layout/main.xml" },
-    };
-
-    BigBuffer buffer(1024);
-    ChunkWriter writer = wrapBufferWithFileExportHeader(&buffer, &resFile);
-    *writer.getBuffer()->nextBlock<uint32_t>() = 42u;
-    writer.finish();
-
-    std::unique_ptr<uint8_t[]> data = util::copy(buffer);
-
-    ResourceFile actualResFile;
-
-    ssize_t offset = unwrapFileExportHeader(data.get(), buffer.size(), &actualResFile, nullptr);
-    ASSERT_GT(offset, 0);
-
-    EXPECT_EQ(offset, getWrappedDataOffset(data.get(), buffer.size(), nullptr));
-
-    EXPECT_EQ(actualResFile.config, test::parseConfigOrDie("sw600dp-v4"));
-    EXPECT_EQ(actualResFile.name, test::parseNameOrDie(u"@android:layout/main.xml"));
-    EXPECT_EQ(actualResFile.source.path, "res/layout/main.xml");
-
-    EXPECT_EQ(*(uint32_t*)(data.get() + offset), 42u);
-}
-
-} // namespace aapt
diff --git a/tools/aapt2/util/Comparators.h b/tools/aapt2/util/Comparators.h
deleted file mode 100644
index 0ee0bf3..0000000
--- a/tools/aapt2/util/Comparators.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AAPT_UTIL_COMPARATORS_H
-#define AAPT_UTIL_COMPARATORS_H
-
-#include "ConfigDescription.h"
-#include "ResourceTable.h"
-
-namespace aapt {
-namespace cmp {
-
-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
-
-#endif /* AAPT_UTIL_COMPARATORS_H */
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index c7b24bc..b6588b6 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -288,8 +288,10 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static boolean nAddFontWeightStyle(long nativeFamily, final String path,
+    /*package*/ static boolean nAddFontWeightStyle(long nativeFamily,
+            final String path, final int index, final List<FontListParser.Axis> axes,
             final int weight, final boolean isItalic) {
+        // 'index' and 'axes' are not supported by java.awt.Font
         final FontFamily_Delegate delegate = getDelegate(nativeFamily);
         if (delegate != null) {
             if (sFontLocation == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index d0dd22f..a10ac00 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -388,21 +388,18 @@
     @LayoutlibDelegate
     /*package*/ static void native_addRoundRect(long nPath, float left, float top, float right,
             float bottom, float[] radii, int dir) {
-        // Java2D doesn't support different rounded corners in each corner, so just use the
-        // first value.
-        native_addRoundRect(nPath, left, top, right, bottom, radii[0], radii[1], dir);
 
-        // there can be a case where this API is used but with similar values for all corners, so
-        // in that case we don't warn.
-        // we only care if 2 corners are different so just compare to the next one.
-        for (int i = 0 ; i < 3 ; i++) {
-            if (radii[i * 2] != radii[(i + 1) * 2] || radii[i * 2 + 1] != radii[(i + 1) * 2 + 1]) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
-                        "Different corner sizes are not supported in Path.addRoundRect.",
-                        null, null /*data*/);
-                break;
-            }
+        Path_Delegate pathDelegate = sManager.getDelegate(nPath);
+        if (pathDelegate == null) {
+            return;
         }
+
+        float[] cornerDimensions = new float[radii.length];
+        for (int i = 0; i < radii.length; i++) {
+            cornerDimensions[i] = 2 * radii[i];
+        }
+        pathDelegate.mPath.append(new RoundRectangle(left, top, right - left, bottom - top,
+                cornerDimensions), false);
     }
 
     @LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
new file mode 100644
index 0000000..edd36e5
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/RoundRectangle.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RectangularShape;
+import java.awt.geom.RoundRectangle2D;
+import java.util.EnumSet;
+import java.util.NoSuchElementException;
+
+/**
+ * Defines a rectangle with rounded corners, where the sizes of the corners
+ * are potentially different.
+ */
+public class RoundRectangle extends RectangularShape {
+    public double x;
+    public double y;
+    public double width;
+    public double height;
+    public double ulWidth;
+    public double ulHeight;
+    public double urWidth;
+    public double urHeight;
+    public double lrWidth;
+    public double lrHeight;
+    public double llWidth;
+    public double llHeight;
+
+    private enum Zone {
+        CLOSE_OUTSIDE,
+        CLOSE_INSIDE,
+        MIDDLE,
+        FAR_INSIDE,
+        FAR_OUTSIDE
+    }
+
+    private final EnumSet<Zone> close = EnumSet.of(Zone.CLOSE_OUTSIDE, Zone.CLOSE_INSIDE);
+    private final EnumSet<Zone> far = EnumSet.of(Zone.FAR_OUTSIDE, Zone.FAR_INSIDE);
+
+    /**
+     * @param cornerDimensions array of 8 floating-point number corresponding to the width and
+     * the height of each corner in the following order: upper-left, upper-right, lower-right,
+     * lower-left. It assumes for the size the same convention as {@link RoundRectangle2D}, that
+     * is that the width and height of a corner correspond to the total width and height of the
+     * ellipse that corner is a quarter of.
+     */
+    public RoundRectangle(float x, float y, float width, float height, float[] cornerDimensions) {
+        if (cornerDimensions.length != 8) {
+            throw new IllegalArgumentException("The array of corner dimensions must have eight " +
+                    "elements");
+        }
+
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+
+        float[] dimensions = cornerDimensions.clone();
+        // If a value is negative, the corresponding corner is squared
+        for (int i = 0; i < dimensions.length; i += 2) {
+            if (dimensions[i] < 0 || dimensions[i + 1] < 0) {
+                dimensions[i] = 0;
+                dimensions[i + 1] = 0;
+            }
+        }
+
+        double topCornerWidth = (dimensions[0] + dimensions[2]) / 2d;
+        double bottomCornerWidth = (dimensions[4] + dimensions[6]) / 2d;
+        double leftCornerHeight = (dimensions[1] + dimensions[7]) / 2d;
+        double rightCornerHeight = (dimensions[3] + dimensions[5]) / 2d;
+
+        // Rescale the corner dimensions if they are bigger than the rectangle
+        double scale = Math.min(1.0, width / topCornerWidth);
+        scale = Math.min(scale, width / bottomCornerWidth);
+        scale = Math.min(scale, height / leftCornerHeight);
+        scale = Math.min(scale, height / rightCornerHeight);
+
+        this.ulWidth = dimensions[0] * scale;
+        this.ulHeight = dimensions[1] * scale;
+        this.urWidth = dimensions[2] * scale;
+        this.urHeight = dimensions[3] * scale;
+        this.lrWidth = dimensions[4] * scale;
+        this.lrHeight = dimensions[5] * scale;
+        this.llWidth = dimensions[6] * scale;
+        this.llHeight = dimensions[7] * scale;
+    }
+
+    @Override
+    public double getX() {
+        return x;
+    }
+
+    @Override
+    public double getY() {
+        return y;
+    }
+
+    @Override
+    public double getWidth() {
+        return width;
+    }
+
+    @Override
+    public double getHeight() {
+        return height;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return (width <= 0d) || (height <= 0d);
+    }
+
+    @Override
+    public void setFrame(double x, double y, double w, double h) {
+        this.x = x;
+        this.y = y;
+        this.width = w;
+        this.height = h;
+    }
+
+    @Override
+    public Rectangle2D getBounds2D() {
+        return new Rectangle2D.Double(x, y, width, height);
+    }
+
+    @Override
+    public boolean contains(double x, double y) {
+        if (isEmpty()) {
+            return false;
+        }
+
+        double x0 = getX();
+        double y0 = getY();
+        double x1 = x0 + getWidth();
+        double y1 = y0 + getHeight();
+        // Check for trivial rejection - point is outside bounding rectangle
+        if (x < x0 || y < y0 || x >= x1 || y >= y1) {
+            return false;
+        }
+
+        double insideTopX0 = x0 + ulWidth / 2d;
+        double insideLeftY0 = y0 + ulHeight / 2d;
+        if (x < insideTopX0 && y < insideLeftY0) {
+            // In the upper-left corner
+            return isInsideCorner(x - insideTopX0, y - insideLeftY0, ulWidth / 2d, ulHeight / 2d);
+        }
+
+        double insideTopX1 = x1 - urWidth / 2d;
+        double insideRightY0 = y0 + urHeight / 2d;
+        if (x > insideTopX1 && y < insideRightY0) {
+            // In the upper-right corner
+            return isInsideCorner(x - insideTopX1, y - insideRightY0, urWidth / 2d, urHeight / 2d);
+        }
+
+        double insideBottomX1 = x1 - lrWidth / 2d;
+        double insideRightY1 = y1 - lrHeight / 2d;
+        if (x > insideBottomX1 && y > insideRightY1) {
+            // In the lower-right corner
+            return isInsideCorner(x - insideBottomX1, y - insideRightY1, lrWidth / 2d,
+                    lrHeight / 2d);
+        }
+
+        double insideBottomX0 = x0 + llWidth / 2d;
+        double insideLeftY1 = y1 - llHeight / 2d;
+        if (x < insideBottomX0 && y > insideLeftY1) {
+            // In the lower-left corner
+            return isInsideCorner(x - insideBottomX0, y - insideLeftY1, llWidth / 2d,
+                    llHeight / 2d);
+        }
+
+        // In the central part of the rectangle
+        return true;
+    }
+
+    private boolean isInsideCorner(double x, double y, double width, double height) {
+        double squareDist = height * height * x * x + width * width * y * y;
+        return squareDist <= width * width * height * height;
+    }
+
+    private Zone classify(double coord, double side1, double arcSize1, double side2,
+            double arcSize2) {
+        if (coord < side1) {
+            return Zone.CLOSE_OUTSIDE;
+        } else if (coord < side1 + arcSize1) {
+            return Zone.CLOSE_INSIDE;
+        } else if (coord < side2 - arcSize2) {
+            return Zone.MIDDLE;
+        } else if (coord < side2) {
+            return Zone.FAR_INSIDE;
+        } else {
+            return Zone.FAR_OUTSIDE;
+        }
+    }
+
+    public boolean intersects(double x, double y, double w, double h) {
+        if (isEmpty() || w <= 0 || h <= 0) {
+            return false;
+        }
+        double x0 = getX();
+        double y0 = getY();
+        double x1 = x0 + getWidth();
+        double y1 = y0 + getHeight();
+        // Check for trivial rejection - bounding rectangles do not intersect
+        if (x + w <= x0 || x >= x1 || y + h <= y0 || y >= y1) {
+            return false;
+        }
+
+        double maxLeftCornerWidth = Math.max(ulWidth, llWidth) / 2d;
+        double maxRightCornerWidth = Math.max(urWidth, lrWidth) / 2d;
+        double maxUpperCornerHeight = Math.max(ulHeight, urHeight) / 2d;
+        double maxLowerCornerHeight = Math.max(llHeight, lrHeight) / 2d;
+        Zone x0class = classify(x, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
+        Zone x1class = classify(x + w, x0, maxLeftCornerWidth, x1, maxRightCornerWidth);
+        Zone y0class = classify(y, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
+        Zone y1class = classify(y + h, y0, maxUpperCornerHeight, y1, maxLowerCornerHeight);
+
+        // Trivially accept if any point is inside inner rectangle
+        if (x0class == Zone.MIDDLE || x1class == Zone.MIDDLE || y0class == Zone.MIDDLE || y1class == Zone.MIDDLE) {
+            return true;
+        }
+        // Trivially accept if either edge spans inner rectangle
+        if ((close.contains(x0class) && far.contains(x1class)) || (close.contains(y0class) &&
+                far.contains(y1class))) {
+            return true;
+        }
+
+        // Since neither edge spans the center, then one of the corners
+        // must be in one of the rounded edges.  We detect this case if
+        // a [xy]0class is 3 or a [xy]1class is 1.  One of those two cases
+        // must be true for each direction.
+        // We now find a "nearest point" to test for being inside a rounded
+        // corner.
+        if (x1class == Zone.CLOSE_INSIDE && y1class == Zone.CLOSE_INSIDE) {
+            // Potentially in upper-left corner
+            x = x + w - x0 - ulWidth / 2d;
+            y = y + h - y0 - ulHeight / 2d;
+            return x > 0 || y > 0 || isInsideCorner(x, y, ulWidth / 2d, ulHeight / 2d);
+        }
+        if (x1class == Zone.CLOSE_INSIDE) {
+            // Potentially in lower-left corner
+            x = x + w - x0 - llWidth / 2d;
+            y = y - y1 + llHeight / 2d;
+            return x > 0 || y < 0 || isInsideCorner(x, y, llWidth / 2d, llHeight / 2d);
+        }
+        if (y1class == Zone.CLOSE_INSIDE) {
+            //Potentially in the upper-right corner
+            x = x - x1 + urWidth / 2d;
+            y = y + h - y0 - urHeight / 2d;
+            return x < 0 || y > 0 || isInsideCorner(x, y, urWidth / 2d, urHeight / 2d);
+        }
+        // Potentially in the lower-right corner
+        x = x - x1 + lrWidth / 2d;
+        y = y - y1 + lrHeight / 2d;
+        return x < 0 || y < 0 || isInsideCorner(x, y, lrWidth / 2d, lrHeight / 2d);
+    }
+
+    @Override
+    public boolean contains(double x, double y, double w, double h) {
+        if (isEmpty() || w <= 0 || h <= 0) {
+            return false;
+        }
+        return (contains(x, y) &&
+                contains(x + w, y) &&
+                contains(x, y + h) &&
+                contains(x + w, y + h));
+    }
+
+    @Override
+    public PathIterator getPathIterator(final AffineTransform at) {
+        return new PathIterator() {
+            int index;
+
+            // ArcIterator.btan(Math.PI/2)
+            public static final double CtrlVal = 0.5522847498307933;
+            private final double ncv = 1.0 - CtrlVal;
+
+            // Coordinates of control points for Bezier curves approximating the straight lines
+            // and corners of the rounded rectangle.
+            private final double[][] ctrlpts = {
+                    {0.0, 0.0, 0.0, ulHeight},
+                    {0.0, 0.0, 1.0, -llHeight},
+                    {0.0, 0.0, 1.0, -llHeight * ncv, 0.0, ncv * llWidth, 1.0, 0.0, 0.0, llWidth,
+                            1.0, 0.0},
+                    {1.0, -lrWidth, 1.0, 0.0},
+                    {1.0, -lrWidth * ncv, 1.0, 0.0, 1.0, 0.0, 1.0, -lrHeight * ncv, 1.0, 0.0, 1.0,
+                            -lrHeight},
+                    {1.0, 0.0, 0.0, urHeight},
+                    {1.0, 0.0, 0.0, ncv * urHeight, 1.0, -urWidth * ncv, 0.0, 0.0, 1.0, -urWidth,
+                            0.0, 0.0},
+                    {0.0, ulWidth, 0.0, 0.0},
+                    {0.0, ncv * ulWidth, 0.0, 0.0, 0.0, 0.0, 0.0, ncv * ulHeight, 0.0, 0.0, 0.0,
+                            ulHeight},
+                    {}
+            };
+            private final int[] types = {
+                    SEG_MOVETO,
+                    SEG_LINETO, SEG_CUBICTO,
+                    SEG_LINETO, SEG_CUBICTO,
+                    SEG_LINETO, SEG_CUBICTO,
+                    SEG_LINETO, SEG_CUBICTO,
+                    SEG_CLOSE,
+            };
+
+            @Override
+            public int getWindingRule() {
+                return WIND_NON_ZERO;
+            }
+
+            @Override
+            public boolean isDone() {
+                return index >= ctrlpts.length;
+            }
+
+            @Override
+            public void next() {
+                index++;
+            }
+
+            @Override
+            public int currentSegment(float[] coords) {
+                if (isDone()) {
+                    throw new NoSuchElementException("roundrect iterator out of bounds");
+                }
+                int nc = 0;
+                double ctrls[] = ctrlpts[index];
+                for (int i = 0; i < ctrls.length; i += 4) {
+                    coords[nc++] = (float) (x + ctrls[i] * width + ctrls[i + 1] / 2d);
+                    coords[nc++] = (float) (y + ctrls[i + 2] * height + ctrls[i + 3] / 2d);
+                }
+                if (at != null) {
+                    at.transform(coords, 0, coords, 0, nc / 2);
+                }
+                return types[index];
+            }
+
+            @Override
+            public int currentSegment(double[] coords) {
+                if (isDone()) {
+                    throw new NoSuchElementException("roundrect iterator out of bounds");
+                }
+                int nc = 0;
+                double ctrls[] = ctrlpts[index];
+                for (int i = 0; i < ctrls.length; i += 4) {
+                    coords[nc++] = x + ctrls[i] * width + ctrls[i + 1] / 2d;
+                    coords[nc++] = y + ctrls[i + 2] * height + ctrls[i + 3] / 2d;
+                }
+                if (at != null) {
+                    at.transform(coords, 0, coords, 0, nc / 2);
+                }
+                return types[index];
+            }
+        };
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 2560c31..8d1b124 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -348,6 +348,11 @@
     }
 
     @Override
+    public void notifyAppStopped(IBinder token) throws RemoteException {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
     public void setEventDispatching(boolean arg0) throws RemoteException {
         // TODO Auto-generated method stub
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 037ce57..fcfbad2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -308,6 +308,11 @@
     }
 
     @Override
+    public String getServicesSystemSharedLibraryPackageName() {
+        return null;
+    }
+
+    @Override
     public FeatureInfo[] getSystemAvailableFeatures() {
         return new FeatureInfo[0];
     }
@@ -318,6 +323,11 @@
     }
 
     @Override
+    public boolean hasSystemFeature(String name, int version) {
+        return false;
+    }
+
+    @Override
     public ResolveInfo resolveActivity(Intent intent, int flags) {
         return null;
     }
@@ -774,7 +784,13 @@
     }
 
     @Override
-    public boolean setPackageSuspendedAsUser(String packageName, boolean suspended, int userId) {
+    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
+            int userId) {
+        return new String[]{};
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
         return false;
     }
 
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 7b8e29a..fe05b0e 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
@@ -236,4 +236,9 @@
     public void prepareToReplaceChildren(IBinder appToken) {
         // pass for now.
     }
+
+    @Override
+    public void updatePointerIcon(IWindow window) {
+        // pass for now.
+    }
 }
diff --git a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java
index 611ed15..9fc1706 100644
--- a/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java
+++ b/wifi/java/android/net/wifi/PasspointManagementObjectDefinition.java
@@ -36,15 +36,15 @@
         mMoTree = moTree;
     }
 
-    public String getmBaseUri() {
+    public String getBaseUri() {
         return mBaseUri;
     }
 
-    public String getmUrn() {
+    public String getUrn() {
         return mUrn;
     }
 
-    public String getmMoTree() {
+    public String getMoTree() {
         return mMoTree;
     }
 
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 503e4a2..7f1ae24 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -23,7 +23,7 @@
 @SystemApi
 public class RttManager {
 
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final String TAG = "RttManager";
 
     /** @deprecated It is Not supported anymore. */
@@ -136,6 +136,9 @@
     public static final int REASON_INVALID_REQUEST          = -4;
     /** Do not have required permission */
     public static final int REASON_PERMISSION_DENIED        = -5;
+    /** Ranging failed because responder role is enabled in STA mode.*/
+    public static final int
+            REASON_INITIATOR_NOT_ALLOWED_WHEN_RESPONDER_ON  = -6;
 
     public static final String DESCRIPTION_KEY  = "android.net.wifi.RttManager.Description";
 
@@ -191,6 +194,8 @@
         public int preambleSupported;
         //RTT bandwidth supported
         public int bwSupported;
+        // Whether STA responder role is supported.
+        public boolean responderSupported;
 
         @Override
         public String toString() {
@@ -244,6 +249,9 @@
 
             sb.append("is supported.");
 
+            sb.append(" STA responder role is ")
+                .append(responderSupported ? "supported" : "not supported.");
+
             return sb.toString();
         }
         /** Implement the Parcelable interface {@hide} */
@@ -261,7 +269,7 @@
             dest.writeInt(lcrSupported ? 1 : 0);
             dest.writeInt(preambleSupported);
             dest.writeInt(bwSupported);
-
+            dest.writeInt(responderSupported ? 1 : 0);
         }
 
         /** Implement the Parcelable interface {@hide} */
@@ -275,6 +283,7 @@
                         capabilities.lcrSupported = in.readInt() == 1 ? true : false;
                         capabilities.preambleSupported = in.readInt();
                         capabilities.bwSupported = in.readInt();
+                        capabilities.responderSupported = (in.readInt() == 1);
                         return capabilities;
                     }
                 /** Implement the Parcelable interface {@hide} */
@@ -898,6 +907,160 @@
         sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener));
     }
 
+    /**
+     * Callbacks for responder operations.
+     * <p>
+     * A {@link ResponderCallback} is the handle to the calling client. {@link RttManager} will keep
+     * a reference to the callback for the entire period when responder is enabled. The same
+     * callback as used in enabling responder needs to be passed for disabling responder.
+     * The client can freely destroy or reuse the callback after {@link RttManager#disableResponder}
+     * is called.
+     */
+    public abstract static class ResponderCallback {
+        /** Callback when responder is enabled. */
+        public abstract void onResponderEnabled(ResponderConfig config);
+        /** Callback when enabling responder failed. */
+        public abstract void onResponderEnableFailure(int reason);
+        // TODO: consider adding onResponderAborted once it's supported.
+    }
+
+    /**
+     * Enable Wi-Fi RTT responder mode on the device. The enabling result will be delivered via
+     * {@code callback}.
+     * <p>
+     * Note calling this method with the same callback when the responder is already enabled won't
+     * change the responder state, a cached {@link ResponderConfig} from the last enabling will be
+     * returned through the callback.
+     *
+     * @param callback Callback for responder enabling/disabling result.
+     * @throws IllegalArgumentException If {@code callback} is null.
+     */
+    public void enableResponder(ResponderCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback cannot be null");
+        }
+        validateChannel();
+        int key = putListenerIfAbsent(callback);
+        sAsyncChannel.sendMessage(CMD_OP_ENABLE_RESPONDER, 0, key);
+    }
+
+    /**
+     * Disable Wi-Fi RTT responder mode on the device. The {@code callback} needs to be the
+     * same one used in {@link #enableResponder(ResponderCallback)}.
+     * <p>
+     * Calling this method when responder isn't enabled won't have any effect. The callback can be
+     * reused for enabling responder after this method is called.
+     *
+     * @param callback The same callback used for enabling responder.
+     * @throws IllegalArgumentException If {@code callback} is null.
+     */
+    public void disableResponder(ResponderCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback cannot be null");
+        }
+        validateChannel();
+        int key = removeListener(callback);
+        if (key == INVALID_KEY) {
+            Log.e(TAG, "responder not enabled yet");
+            return;
+        }
+        sAsyncChannel.sendMessage(CMD_OP_DISABLE_RESPONDER, 0, key);
+    }
+
+    /**
+     * Configuration used for RTT responder mode. The configuration information can be used by a
+     * peer device to range the responder.
+     *
+     * @see ScanResult
+     */
+    public static class ResponderConfig implements Parcelable {
+
+        // TODO: make all fields final once we can get mac address from responder HAL APIs.
+        /**
+         * Wi-Fi mac address used for responder mode.
+         */
+        public String macAddress = "";
+
+        /**
+         * The primary 20 MHz frequency (in MHz) of the channel where responder is enabled.
+         * @see ScanResult#frequency
+         */
+        public int frequency;
+
+        /**
+         * Center frequency of the channel where responder is enabled on. Only in use when channel
+         * width is at least 40MHz.
+         * @see ScanResult#centerFreq0
+         */
+        public int centerFreq0;
+
+        /**
+         * Center frequency of the second segment when channel width is 80 + 80 MHz.
+         * @see ScanResult#centerFreq1
+         */
+        public int centerFreq1;
+
+        /**
+         * Width of the channel where responder is enabled on.
+         * @see ScanResult#channelWidth
+         */
+        public int channelWidth;
+
+        /**
+         * Preamble supported by responder.
+         */
+        public int preamble;
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append("macAddress = ").append(macAddress)
+                    .append(" frequency = ").append(frequency)
+                    .append(" centerFreq0 = ").append(centerFreq0)
+                    .append(" centerFreq1 = ").append(centerFreq1)
+                    .append(" channelWidth = ").append(channelWidth)
+                    .append(" preamble = ").append(preamble);
+            return builder.toString();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(macAddress);
+            dest.writeInt(frequency);
+            dest.writeInt(centerFreq0);
+            dest.writeInt(centerFreq1);
+            dest.writeInt(channelWidth);
+            dest.writeInt(preamble);
+        }
+
+        /** Implement {@link Parcelable} interface */
+        public static final Parcelable.Creator<ResponderConfig> CREATOR =
+                new Parcelable.Creator<ResponderConfig>() {
+            @Override
+            public ResponderConfig createFromParcel(Parcel in) {
+                ResponderConfig config = new ResponderConfig();
+                config.macAddress = in.readString();
+                config.frequency = in.readInt();
+                config.centerFreq0 = in.readInt();
+                config.centerFreq1 = in.readInt();
+                config.channelWidth = in.readInt();
+                config.preamble = in.readInt();
+                return config;
+            }
+
+            @Override
+            public ResponderConfig[] newArray(int size) {
+                return new ResponderConfig[size];
+            }
+        };
+
+    }
+
     /* private methods */
     public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER;
 
@@ -906,6 +1069,12 @@
     public static final int CMD_OP_FAILED               = BASE + 2;
     public static final int CMD_OP_SUCCEEDED            = BASE + 3;
     public static final int CMD_OP_ABORTED              = BASE + 4;
+    public static final int CMD_OP_ENABLE_RESPONDER     = BASE + 5;
+    public static final int CMD_OP_DISABLE_RESPONDER    = BASE + 6;
+    public static final int
+            CMD_OP_ENALBE_RESPONDER_SUCCEEDED           = BASE + 7;
+    public static final int
+            CMD_OP_ENALBE_RESPONDER_FAILED              = BASE + 8;
 
     private Context mContext;
     private IRttManager mService;
@@ -992,6 +1161,23 @@
         return key;
     }
 
+    // Insert a listener if it doesn't exist in sListenerMap. Returns the key of the listener.
+    private static int putListenerIfAbsent(Object listener) {
+        if (listener == null) return INVALID_KEY;
+        synchronized (sListenerMapLock) {
+            int key = getListenerKey(listener);
+            if (key != INVALID_KEY) {
+                return key;
+            }
+            do {
+                key = sListenerKey++;
+            } while (key == INVALID_KEY);
+            sListenerMap.put(key, listener);
+            return key;
+        }
+
+    }
+
     private static Object getListener(int key) {
         if (key == INVALID_KEY) return null;
         synchronized (sListenerMapLock) {
@@ -1047,9 +1233,9 @@
                         // to fail and throw an exception
                         sAsyncChannel = null;
                     }
-                    sConnected.countDown();
                     return;
                 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+                    sConnected.countDown();
                     return;
                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
                     Log.e(TAG, "Channel connection lost");
@@ -1082,6 +1268,14 @@
                     ((RttListener) listener).onAborted();
                     removeListener(msg.arg2);
                     break;
+                case CMD_OP_ENALBE_RESPONDER_SUCCEEDED:
+                    ResponderConfig config = (ResponderConfig) msg.obj;
+                    ((ResponderCallback) (listener)).onResponderEnabled(config);
+                    break;
+                case CMD_OP_ENALBE_RESPONDER_FAILED:
+                    ((ResponderCallback) (listener)).onResponderEnableFailure(msg.arg1);
+                    removeListener(msg.arg2);
+                    break;
                 default:
                     if (DBG) Log.d(TAG, "Ignoring message " + msg.what);
                     return;
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 4a86c59..31da670 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -332,6 +332,7 @@
     public static class InformationElement {
         public static final int EID_SSID = 0;
         public static final int EID_BSS_LOAD = 11;
+        public static final int EID_RSN = 48;
         public static final int EID_HT_OPERATION = 61;
         public static final int EID_INTERWORKING = 107;
         public static final int EID_ROAMING_CONSORTIUM = 111;
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index a9132a5..cce8386 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -26,7 +26,12 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.text.TextUtils;
+import android.util.BackupUtils;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashMap;
@@ -37,6 +42,10 @@
  */
 public class WifiConfiguration implements Parcelable {
     private static final String TAG = "WifiConfiguration";
+    /**
+     * Current Version of the Backup Serializer.
+    */
+    private static final int BACKUP_VERSION = 2;
     /** {@hide} */
     public static final String ssidVarName = "ssid";
     /** {@hide} */
@@ -230,12 +239,24 @@
     public String BSSID;
 
     /**
+     * 2GHz band.
+     * @hide
+     */
+    public static final int AP_BAND_2GHZ = 0;
+
+    /**
+     * 5GHz band.
+     * @hide
+     */
+    public static final int AP_BAND_5GHZ = 1;
+
+    /**
      * The band which AP resides on
      * 0-2G  1-5G
      * By default, 2G is chosen
      * @hide
      */
-    public int apBand = 0;
+    public int apBand = AP_BAND_2GHZ;
 
     /**
      * The channel which AP resides on,currently, US only
@@ -1450,10 +1471,10 @@
             if (diff <= 0) {
                 sbuf.append(" blackListed since <incorrect>");
             } else {
-                sbuf.append(" blackListed: ").append(Long.toString(diff/1000)).append( "sec ");
+                sbuf.append(" blackListed: ").append(Long.toString(diff / 1000)).append("sec ");
             }
         }
-        if (creatorUid != 0)  sbuf.append(" cuid=" + Integer.toString(creatorUid));
+        if (creatorUid != 0) sbuf.append(" cuid=" + creatorUid);
         if (creatorName != null) sbuf.append(" cname=" + creatorName);
         if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid);
         if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName);
@@ -1468,7 +1489,7 @@
             if (diff <= 0) {
                 sbuf.append("lastConnected since <incorrect>");
             } else {
-                sbuf.append("lastConnected: ").append(Long.toString(diff/1000)).append( "sec ");
+                sbuf.append("lastConnected: ").append(Long.toString(diff / 1000)).append("sec ");
             }
         }
         if (this.lastConnectionFailure != 0) {
@@ -1477,8 +1498,8 @@
             if (diff <= 0) {
                 sbuf.append("lastConnectionFailure since <incorrect> ");
             } else {
-                sbuf.append("lastConnectionFailure: ").append(Long.toString(diff/1000));
-                sbuf.append( "sec ");
+                sbuf.append("lastConnectionFailure: ").append(Long.toString(diff / 1000));
+                sbuf.append("sec ");
             }
         }
         if (this.lastRoamingFailure != 0) {
@@ -1487,20 +1508,19 @@
             if (diff <= 0) {
                 sbuf.append("lastRoamingFailure since <incorrect> ");
             } else {
-                sbuf.append("lastRoamingFailure: ").append(Long.toString(diff/1000));
-                sbuf.append( "sec ");
+                sbuf.append("lastRoamingFailure: ").append(Long.toString(diff / 1000));
+                sbuf.append("sec ");
             }
         }
         sbuf.append("roamingFailureBlackListTimeMilli: ").
                 append(Long.toString(this.roamingFailureBlackListTimeMilli));
         sbuf.append('\n');
         if (this.linkedConfigurations != null) {
-            for(String key : this.linkedConfigurations.keySet()) {
+            for (String key : this.linkedConfigurations.keySet()) {
                 sbuf.append(" linked: ").append(key);
                 sbuf.append('\n');
             }
         }
-
         sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI);
         sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI);
         sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI);
@@ -1748,11 +1768,6 @@
     }
 
     /** @hide */
-    public boolean isVisibleToUser(int userId) {
-        return shared || (UserHandle.getUserId(creatorUid) == userId);
-    }
-
-    /** @hide */
     public void setPasspointManagementObjectTree(String passpointManagementObjectTree) {
         mPasspointManagementObjectTree = passpointManagementObjectTree;
     }
@@ -1990,4 +2005,43 @@
                 return new WifiConfiguration[size];
             }
         };
-}
+
+    /**
+     * Serializes the object for backup
+     * @hide
+     */
+    public byte[] getBytesForBackup() throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream out = new DataOutputStream(baos);
+
+        out.writeInt(BACKUP_VERSION);
+        BackupUtils.writeString(out, SSID);
+        out.writeInt(apBand);
+        out.writeInt(apChannel);
+        BackupUtils.writeString(out, preSharedKey);
+        out.writeInt(getAuthType());
+        return baos.toByteArray();
+    }
+
+    /**
+     * Deserializes a byte array into the WiFiConfiguration Object
+     * @hide
+     */
+    public static WifiConfiguration getWifiConfigFromBackup(DataInputStream in) throws IOException,
+            BackupUtils.BadVersionException {
+        WifiConfiguration config = new WifiConfiguration();
+        int version = in.readInt();
+        if (version < 1 || version > BACKUP_VERSION) {
+            throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
+        }
+
+        if (version == 1) return null; // Version 1 is a bad dataset.
+
+        config.SSID = BackupUtils.readString(in);
+        config.apBand = in.readInt();
+        config.apChannel = in.readInt();
+        config.preSharedKey = BackupUtils.readString(in);
+        config.allowedKeyManagement.set(in.readInt());
+        return config;
+    }
+}
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index a0dbd85..362738e 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -101,6 +101,8 @@
     /** @hide */
     public static final String CA_CERT_KEY         = "ca_cert";
     /** @hide */
+    public static final String CA_PATH_KEY         = "ca_path";
+    /** @hide */
     public static final String ENGINE_KEY          = "engine";
     /** @hide */
     public static final String ENGINE_ID_KEY       = "engine_id";
@@ -625,6 +627,33 @@
         mCaCerts = null;
     }
 
+    /**
+     * Set the ca_path directive on wpa_supplicant.
+     *
+     * From wpa_supplicant documentation:
+     *
+     * Directory path for CA certificate files (PEM). This path may contain
+     * multiple CA certificates in OpenSSL format. Common use for this is to
+     * point to system trusted CA list which is often installed into directory
+     * like /etc/ssl/certs. If configured, these certificates are added to the
+     * list of trusted CAs. ca_cert may also be included in that case, but it is
+     * not required.
+     * @param domain The path for CA certificate files
+     * @hide
+     */
+    public void setCaPath(String path) {
+        setFieldValue(CA_PATH_KEY, path);
+    }
+
+    /**
+     * Get the domain_suffix_match value. See setDomSuffixMatch.
+     * @return The path for CA certificate files.
+     * @hide
+     */
+    public String getCaPath() {
+        return getFieldValue(CA_PATH_KEY, "");
+    }
+
     /** Set Client certificate alias.
      *
      * <p> See the {@link android.security.KeyChain} for details on installing or choosing
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 2ad3c2e..4921073 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -44,6 +44,7 @@
 import com.android.internal.util.Protocol;
 
 import java.net.InetAddress;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
@@ -892,6 +893,24 @@
     }
 
     /**
+     * Sets whether or not the given network is metered from a network policy
+     * point of view. A network should be classified as metered when the user is
+     * sensitive to heavy data usage on that connection due to monetary costs,
+     * data limitations or battery/performance issues. A typical example would
+     * be a wifi connection where the user was being charged for usage.
+     * @param netId the integer that identifies the network configuration
+     * to the supplicant.
+     * @param isMetered True to mark the network as metered.
+     * @return {@code true} if the operation succeeded.
+     * @hide
+     */
+    @SystemApi
+    public boolean setMetered(int netId, boolean isMetered) {
+        // TODO(jjoslin): Implement
+        return false;
+    }
+
+    /**
      * Remove the specified network from the list of configured networks.
      * This may result in the asynchronous delivery of state change
      * events.
@@ -1301,13 +1320,15 @@
      * @return the list of access points found in the most recent scan. An app must hold
      * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
-     * in order to get valid results.
+     * in order to get valid results.  If there is a remote exception (e.g., either a communication
+     * problem with the system service or an exception within the framework) an empty list will be
+     * returned.
      */
     public List<ScanResult> getScanResults() {
         try {
             return mService.getScanResults(mContext.getOpPackageName());
         } catch (RemoteException e) {
-            return null;
+            return new ArrayList<ScanResult>();
         }
     }
 
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 44be671..2373754 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -155,10 +155,6 @@
      * Do not place scans in the chip's scan history buffer
      */
     public static final int REPORT_EVENT_NO_BATCH = (1 << 2);
-    /**
-     * report full scan results and completion event to the context hub
-     */
-    public static final int REPORT_EVENT_CONTEXT_HUB = (1 << 3);
 
     /**
      * scan configuration parameters to be sent to {@link #startBackgroundScan}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
index 5c18bd7..9e6ed4e 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
@@ -36,7 +36,7 @@
  */
 public class WifiNanEventListener {
     private static final String TAG = "WifiNanEventListener";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index cb82268..667c4b1 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -38,7 +38,7 @@
  */
 public class WifiNanManager {
     private static final String TAG = "WifiNanManager";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     private IBinder mBinder;
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
index d0a9410..bc1787f 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -27,7 +27,7 @@
  */
 public class WifiNanSession {
     private static final String TAG = "WifiNanSession";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
index 0925087..b9af7def 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
@@ -43,7 +43,7 @@
  */
 public class WifiNanSessionListener {
     private static final String TAG = "WifiNanSessionListener";
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
     private static final boolean VDBG = false; // STOPSHIP if true
 
     /**